00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _terimber_memdb_hpp_
00029 #define _terimber_memdb_hpp_
00030
00031 #include "memdb/memdb.h"
00032 #include "base/common.hpp"
00033 #include "db/db.hpp"
00034
00035 BEGIN_TERIMBER_NAMESPACE
00036 #pragma pack(4)
00037
00038 static
00039 inline
00040 int
00041 compare_db_value(dbtypes type, const terimber_db_value& first, const terimber_db_value second, bool case_insensitive)
00042 {
00043 if (first.nullVal)
00044 return second.nullVal ? 0 : -1;
00045 else if (second.nullVal)
00046 return 1;
00047
00048 return compare_value(dbserver_impl::convert_types(type), first.val, second.val, false, case_insensitive);
00049 }
00050
00051 inline
00052 bool
00053 memdb_rowset_less::operator()(const memdb_rowset_citerator_t& first, const memdb_rowset_citerator_t& second) const
00054 {
00055
00056 size_t length = _info.size();
00057 bool first_lookup = false;
00058 bool second_lookup = false;
00059
00060 if (first->_status == status_lookup)
00061 {
00062 first_lookup = true;
00063 length = first->_row.size();
00064 }
00065 else if (second->_status == status_lookup)
00066 {
00067 second_lookup = true;
00068 length = second->_row.size();
00069 }
00070
00071 if (first->_status == status_deleted
00072 || second->_status == status_deleted)
00073 return first->_status < status_deleted;
00074
00075
00076 for (size_t index = 0; index < length; ++index)
00077 {
00078 int res = compare_db_value(_info[index]._type, first->_row[first_lookup ? index : _info[index]._index], second->_row[second_lookup ? index : _info[index]._index], _info[index]._case_insensitive);
00079 if (res == 0)
00080 continue;
00081 else
00082 return _info[index]._asc_sort ? res < 0 : res > 0;
00083 }
00084
00085 return false;
00086 }
00087
00088 template < class S, class C >
00089 bool
00090 copy_db_row(const S* source, memdb_row& row, C& cols, size_t col_count, byte_allocator& all, string_t& err)
00091 {
00092
00093 for (size_t icol = 0; icol < col_count; ++icol)
00094 {
00095 row._row[icol].nullVal = source->get_value_is_null(icol);
00096 if (!row._row[icol].nullVal)
00097 {
00098 switch (cols[icol]._type)
00099 {
00100 case db_bool:
00101 row._row[icol].val.boolVal = source->get_value_as_bool(icol);
00102 break;
00103 case db_sb1:
00104 row._row[icol].val.cVal = source->get_value_as_char(icol);
00105 break;
00106 case db_ub1:
00107 row._row[icol].val.bVal = source->get_value_as_byte(icol);
00108 break;
00109 case db_sb2:
00110 row._row[icol].val.iVal = source->get_value_as_short(icol);
00111 break;
00112 case db_ub2:
00113 row._row[icol].val.uiVal = source->get_value_as_word(icol);
00114 break;
00115 case db_sb4:
00116 row._row[icol].val.lVal = source->get_value_as_long(icol);
00117 break;
00118 case db_ub4:
00119 row._row[icol].val.ulVal = source->get_value_as_dword(icol);
00120 break;
00121 case db_float:
00122 row._row[icol].val.fltVal = source->get_value_as_float(icol);
00123 break;
00124 case db_double:
00125 #ifdef OS_64BIT
00126 row._row[icol].val.dblVal = source->get_value_as_double(icol);
00127 #else
00128 {
00129 double* dummy = 0;
00130 dummy = (double*)all.allocate(sizeof(double));
00131 if (!dummy)
00132 {
00133 err = "no enough memory";
00134 return false;
00135 }
00136
00137 *dummy = source->get_value_as_double(icol);
00138 row._row[icol].val.dblVal = dummy;
00139 }
00140 #endif
00141 break;
00142 case db_sb8:
00143 case db_date:
00144 #ifdef OS_64BIT
00145 row._row[icol].val.intVal = source->get_value_as_long64(icol);
00146 #else
00147 {
00148 sb8_t* dummy = 0;
00149 dummy = (sb8_t*)all.allocate(sizeof(sb8_t));
00150 if (!dummy)
00151 {
00152 err = "no enough memory";
00153 return false;
00154 }
00155 *dummy = source->get_value_as_long64(icol);
00156 row._row[icol].val.intVal = dummy;
00157 }
00158 #endif
00159 break;
00160 case db_ub8:
00161 #ifdef OS_64BIT
00162 row._row[icol].val.uintVal = source->get_value_as_dword64(icol);
00163 #else
00164 {
00165 ub8_t* dummy = 0;
00166 dummy = (ub8_t*)all.allocate(sizeof(ub8_t));
00167 if (!dummy)
00168 {
00169 err = "no enough memory";
00170 return false;
00171 }
00172 *dummy = source->get_value_as_dword64(icol);
00173 row._row[icol].val.uintVal = dummy;
00174 }
00175 #endif
00176 break;
00177 case db_decimal:
00178 case db_numeric:
00179 {
00180 const char* buf = source->get_value_as_numeric(icol, '.');
00181 size_t len = (buf) ? strlen(buf) : 0;
00182 numeric conv(buf, len, '.', &all);
00183 ub1_t* buff = (ub1_t*)all.allocate(conv.orcl_len());
00184 if (!buff)
00185 {
00186 err = "no enough memory";
00187 return false;
00188 }
00189
00190 if (!conv.persist_orcl(buff))
00191 {
00192 err = "invalid numeric format";
00193 return false;
00194 }
00195
00196 row._row[icol].val.bufVal = buff;
00197 }
00198 break;
00199 case db_string:
00200 row._row[icol].val.strVal = copy_string(source->get_value_as_string(icol), all, os_minus_one);
00201 break;
00202 case db_wstring:
00203 row._row[icol].val.wstrVal = copy_string(source->get_value_as_wstring(icol), all, os_minus_one);
00204 break;
00205 case db_binary:
00206 {
00207 const ub1_t* buf = source->get_value_as_binary_ptr(icol);
00208 size_t len = *(size_t*)buf;
00209 ub1_t* dummy = (ub1_t*)all.allocate(len + sizeof(size_t));
00210 if (!dummy)
00211 {
00212 err = "no enough memory";
00213 return false;
00214 }
00215
00216 *(size_t*)dummy = len;
00217 if (len)
00218 memcpy(dummy + sizeof(size_t), buf + sizeof(size_t), len);
00219
00220 row._row[icol].val.bufVal = dummy;
00221 }
00222 break;
00223 case db_guid:
00224 {
00225 guid_t* dummy = (guid_t*)all.allocate(sizeof(guid_t));
00226 if (!dummy)
00227 {
00228 err = "no enough memory";
00229 return false;
00230 }
00231 source->get_value_as_guid(icol, *dummy);
00232 row._row[icol].val.guidVal = dummy;
00233 }
00234 break;
00235 }
00236 }
00237 }
00238
00239 return true;
00240 }
00241
00242
00243
00244 #pragma pack()
00245 END_TERIMBER_NAMESPACE
00246
00247 #endif // _terimber_memdb_h_