📄 testoibasic.cpp
字号:
}static intcreateindex(Par par){ const Tab& tab = par.tab(); for (unsigned i = 0; i < tab.m_itabs; i++) { if (tab.m_itab[i] == 0) continue; const ITab& itab = *tab.m_itab[i]; CHK(createindex(par, itab) == 0); } return 0;}// data sets// Val - typed column valuestruct Val { const Col& m_col; union { Uint32 m_uint32; unsigned char* m_char; unsigned char* m_varchar; unsigned char* m_longvarchar; }; Val(const Col& col); ~Val(); void copy(const Val& val2); void copy(const void* addr); const void* dataaddr() const; bool m_null; int equal(Par par) const; int equal(Par par, const ICol& icol) const; int setval(Par par) const; void calc(Par par, unsigned i); void calckey(Par par, unsigned i); void calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf); void calcnokey(Par par); void calcnokeychars(Par par, unsigned& n, unsigned char* buf); int verify(Par par, const Val& val2) const; int cmp(Par par, const Val& val2) const; int cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const;private: Val& operator=(const Val& val2);};static NdbOut&operator<<(NdbOut& out, const Val& val);Val::Val(const Col& col) : m_col(col){ switch (col.m_type) { case Col::Unsigned: break; case Col::Char: m_char = new unsigned char [col.m_bytelength]; break; case Col::Varchar: m_varchar = new unsigned char [1 + col.m_bytelength]; break; case Col::Longvarchar: m_longvarchar = new unsigned char [2 + col.m_bytelength]; break; default: assert(false); break; }}Val::~Val(){ const Col& col = m_col; switch (col.m_type) { case Col::Unsigned: break; case Col::Char: delete [] m_char; break; case Col::Varchar: delete [] m_varchar; break; case Col::Longvarchar: delete [] m_longvarchar; break; default: assert(false); break; }}voidVal::copy(const Val& val2){ const Col& col = m_col; const Col& col2 = val2.m_col; assert(col.m_type == col2.m_type && col.m_length == col2.m_length); if (val2.m_null) { m_null = true; return; } copy(val2.dataaddr());}voidVal::copy(const void* addr){ const Col& col = m_col; switch (col.m_type) { case Col::Unsigned: m_uint32 = *(const Uint32*)addr; break; case Col::Char: memcpy(m_char, addr, col.m_bytelength); break; case Col::Varchar: memcpy(m_varchar, addr, 1 + col.m_bytelength); break; case Col::Longvarchar: memcpy(m_longvarchar, addr, 2 + col.m_bytelength); break; default: assert(false); break; } m_null = false;}const void*Val::dataaddr() const{ const Col& col = m_col; switch (col.m_type) { case Col::Unsigned: return &m_uint32; case Col::Char: return m_char; case Col::Varchar: return m_varchar; case Col::Longvarchar: return m_longvarchar; default: break; } assert(false); return 0;}intVal::equal(Par par) const{ Con& con = par.con(); const Col& col = m_col; assert(col.m_pk && ! m_null); const char* addr = (const char*)dataaddr(); LL5("equal [" << col << "] " << *this); CHK(con.equal(col.m_num, addr) == 0); return 0;}intVal::equal(Par par, const ICol& icol) const{ Con& con = par.con(); assert(! m_null); const char* addr = (const char*)dataaddr(); LL5("equal [" << icol << "] " << *this); CHK(con.equal(icol.m_num, addr) == 0); return 0;}intVal::setval(Par par) const{ Con& con = par.con(); const Col& col = m_col; assert(! col.m_pk); const char* addr = ! m_null ? (const char*)dataaddr() : 0; LL5("setval [" << col << "] " << *this); CHK(con.setValue(col.m_num, addr) == 0); return 0;}voidVal::calc(Par par, unsigned i){ const Col& col = m_col; col.m_pk ? calckey(par, i) : calcnokey(par); if (! m_null) col.wellformed(dataaddr());}voidVal::calckey(Par par, unsigned i){ const Col& col = m_col; m_null = false; switch (col.m_type) { case Col::Unsigned: m_uint32 = i; break; case Col::Char: { const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; unsigned n = 0; calckeychars(par, i, n, m_char); // extend by appropriate space (*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20); } break; case Col::Varchar: { unsigned n = 0; calckeychars(par, i, n, m_varchar + 1); // set length and pad with nulls m_varchar[0] = n; memset(&m_varchar[1 + n], 0, col.m_bytelength - n); } break; case Col::Longvarchar: { unsigned n = 0; calckeychars(par, i, n, m_longvarchar + 2); // set length and pad with nulls m_longvarchar[0] = (n & 0xff); m_longvarchar[1] = (n >> 8); memset(&m_longvarchar[2 + n], 0, col.m_bytelength - n); } break; default: assert(false); break; }}voidVal::calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf){ const Col& col = m_col; const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; n = 0; unsigned len = 0; while (len < col.m_length) { if (i % (1 + n) == 0) { break; } const Chr& chr = chs->m_chr[i % maxcharcount]; assert(n + chr.m_size <= col.m_bytelength); memcpy(buf + n, chr.m_bytes, chr.m_size); n += chr.m_size; len++; }}voidVal::calcnokey(Par par){ const Col& col = m_col; m_null = false; if (col.m_nullable && urandom(100) < par.m_pctnull) { m_null = true; return; } int r = irandom((par.m_pctrange * par.m_range) / 100); if (par.m_bdir != 0 && urandom(10) != 0) { if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0) r = -r; } unsigned v = par.m_range + r; switch (col.m_type) { case Col::Unsigned: m_uint32 = v; break; case Col::Char: { const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; unsigned n = 0; calcnokeychars(par, n, m_char); // extend by appropriate space (*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20); } break; case Col::Varchar: { unsigned n = 0; calcnokeychars(par, n, m_varchar + 1); // set length and pad with nulls m_varchar[0] = n; memset(&m_varchar[1 + n], 0, col.m_bytelength - n); } break; case Col::Longvarchar: { unsigned n = 0; calcnokeychars(par, n, m_longvarchar + 2); // set length and pad with nulls m_longvarchar[0] = (n & 0xff); m_longvarchar[1] = (n >> 8); memset(&m_longvarchar[2 + n], 0, col.m_bytelength - n); } break; default: assert(false); break; }}voidVal::calcnokeychars(Par par, unsigned& n, unsigned char* buf){ const Col& col = m_col; const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; n = 0; unsigned len = 0; while (len < col.m_length) { if (urandom(1 + col.m_bytelength) == 0) { break; } unsigned half = maxcharcount / 2; int r = irandom((par.m_pctrange * half) / 100); if (par.m_bdir != 0 && urandom(10) != 0) { if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0) r = -r; } unsigned i = half + r; assert(i < maxcharcount); const Chr& chr = chs->m_chr[i]; assert(n + chr.m_size <= col.m_bytelength); memcpy(buf + n, chr.m_bytes, chr.m_size); n += chr.m_size; len++; }}intVal::verify(Par par, const Val& val2) const{ CHK(cmp(par, val2) == 0); return 0;}intVal::cmp(Par par, const Val& val2) const{ const Col& col = m_col; const Col& col2 = val2.m_col; assert(col.equal(col2)); if (m_null || val2.m_null) { if (! m_null) return +1; if (! val2.m_null) return -1; return 0; } // verify data formats col.wellformed(dataaddr()); col.wellformed(val2.dataaddr()); // compare switch (col.m_type) { case Col::Unsigned: { if (m_uint32 < val2.m_uint32) return -1; if (m_uint32 > val2.m_uint32) return +1; return 0; } break; case Col::Char: { unsigned len = col.m_bytelength; return cmpchars(par, m_char, len, val2.m_char, len); } break; case Col::Varchar: { unsigned len1 = m_varchar[0]; unsigned len2 = val2.m_varchar[0]; return cmpchars(par, m_varchar + 1, len1, val2.m_varchar + 1, len2); } break; case Col::Longvarchar: { unsigned len1 = m_longvarchar[0] + (m_longvarchar[1] << 8); unsigned len2 = val2.m_longvarchar[0] + (val2.m_longvarchar[1] << 8); return cmpchars(par, m_longvarchar + 2, len1, val2.m_longvarchar + 2, len2); } break; default: break; } assert(false); return 0;}intVal::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const{ const Col& col = m_col; const Chs* chs = col.m_chs; CHARSET_INFO* cs = chs->m_cs; int k; if (! par.m_collsp) { unsigned char x1[maxxmulsize * 8000]; unsigned char x2[maxxmulsize * 8000]; // make strxfrm pad both to same length unsigned len = maxxmulsize * col.m_bytelength; int n1 = NdbSqlUtil::strnxfrm_bug7284(cs, x1, chs->m_xmul * len, buf1, len1); int n2 = NdbSqlUtil::strnxfrm_bug7284(cs, x2, chs->m_xmul * len, buf2, len2); assert(n1 != -1 && n1 == n2); k = memcmp(x1, x2, n1); } else { k = (*cs->coll->strnncollsp)(cs, buf1, len1, buf2, len2, false); } return k < 0 ? -1 : k > 0 ? +1 : 0;}static voidprintstring(NdbOut& out, const unsigned char* str, unsigned len, bool showlen){ char buf[4 * 8000]; char *p = buf; *p++ = '['; if (showlen) { sprintf(p, "%u:", len); p += strlen(p); } for (unsigned i = 0; i < len; i++) { unsigned char c = str[i]; if (c == '\\') { *p++ = '\\'; *p++ = c; } else if (0x20 <= c && c < 0x7e) { *p++ = c; } else { *p++ = '\\'; *p++ = hexstr[c >> 4]; *p++ = hexstr[c & 15]; } } *p++ = ']'; *p = 0; out << buf;}static NdbOut&operator<<(NdbOut& out, const Val& val){ const Col& col = val.m_col; if (val.m_null) { out << "NULL"; return out; } switch (col.m_type) { case Col::Unsigned: out << val.m_uint32; break; case Col::Char: { unsigned len = col.m_bytelength; printstring(out, val.m_char, len, false); } break; case Col::Varchar: { unsigned len = val.m_varchar[0]; printstring(out, val.m_varchar + 1, len, true); } break; case Col::Longvarchar: { unsigned len = val.m_longvarchar[0] + (val.m_longvarchar[1] << 8); printstring(out, val.m_longvarchar + 2, len, true); } break; default: out << "type" << col.m_type; assert(false); break; } return out;}// Row - table tuplestruct Row { const Tab& m_tab; Val** m_val; bool m_exist; enum Op { NoOp = 0, ReadOp = 1, InsOp = 2, UpdOp = 4, DelOp = 8, AnyOp = 15 }; Op m_pending; Row* m_dbrow; // copy of db row before update Row(const Tab& tab); ~Row(); void copy(const Row& row2); void calc(Par par, unsigned i, unsigned mask = 0); const Row& dbrow() const; int verify(Par par, const Row& row2) const; int insrow(Par par); int updrow(Par par); int updrow(Par par, const ITab& itab); int delrow(Par par); int delrow(Par par, const ITab& itab); int selrow(Par par); int selrow(Par par, const ITab& itab); int setrow(Par par); int cmp(Par par, const Row& row2) const; int cmp(Par par, const Row& row2, const ITab& itab) const;private: Row& operator=(const Row& row2);};Row::Row(const Tab& tab) : m_tab(tab){ m_val = new Val* [tab.m_cols]; for (unsigned k = 0; k < tab.m_cols; k++) { const Col& col = *tab.m_col[k]; m_val[k] = new Val(col); } m_exist = false; m_pending = NoOp; m_dbrow = 0;}Row::~Row(){ const Tab& tab = m_tab; for (unsigned k = 0; k < tab.m_cols; k++) { delete m_val[k]; } delete [] m_val; delete m_dbrow;}voidRow::copy(const Row& row2){ const Tab& tab = m_tab; assert(&tab == &row2.m_tab); for (unsigned k = 0; k < tab.m_cols; k++) { Val& val = *m_val[k]; const Val& val2 = *row2.m_val[k]; val.copy(val2); } m_exist = row2.m_exist; m_pending = row2.m_pending; if (row2.m_dbrow == 0) { m_dbrow = 0; } else { assert(row2.m_dbrow->m_dbrow == 0); if (m_dbrow == 0) m_dbrow = new Row(tab); m_dbrow->copy(*row2.m_dbrow); }}void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -