/*================================================================= Copyright (C) 2014 BizStation Corp All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =================================================================*/ #pragma hdrstop #include "queryData.h" #include <bzs/db/protocol/tdap/mysql/characterset.h> #include <iostream> #pragma package(smart_init) using namespace bzs::db::protocol::tdap::client; using namespace bzs::db::protocol::tdap; #ifndef USE_PSQL_DATABASE #define USER_STRING_TYPE ft_myvarchar #define GROUP_STRING_TYPE ft_myvarbinary #define BLOB_TYPE ft_myblob #else #define USER_STRING_TYPE ft_zstring #define GROUP_STRING_TYPE ft_zstring #define BLOB_TYPE ft_blob #endif const _TCHAR* name_field_str(_TCHAR* buf) { #ifdef LINUX return "名前"; #else #ifdef _UNICODE return L"名前"; #else WideCharToMultiByte(CP_UTF8, 0, L"名前", -1, buf, 30, NULL, NULL); return buf; #endif #endif } bool showDbdefError(dbdef* def, const _TCHAR* msg) { std::tcout << msg << _T(" erorr:No.") << def->stat(); return false; } bool showTableError(table* tb, const _TCHAR* msg) { std::tcout << msg << _T(" erorr:No.") << tb->stat(); return false; } bool showDbError(database* db, const _TCHAR* msg) { std::tcout << msg << _T(" erorr:No.") << db->stat(); return false; } bool createUserTable(dbdef* def) { short tableid = 1; tabledef t; tabledef* td = &t; td->charsetIndex = mysql::charsetIndex(GetACP()); td->schemaCodePage = CP_UTF8; td->id = tableid; td->setTableName(_T("user")); td->setFileName(_T("user.dat")); def->insertTable(td); if (def->stat() != 0) return showDbdefError(def, _T("user insertTable")); short filedIndex = 0; fielddef* fd = def->insertField(tableid, filedIndex); fd->setName(_T("id")); fd->type = ft_autoinc; fd->len = 4; ++filedIndex; fd = def->insertField(tableid, filedIndex); _TCHAR tmp[30]; fd->setName(name_field_str(tmp)); fd->type = USER_STRING_TYPE; fd->setLenByCharnum(20); ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("group")); fd->type = ft_integer; fd->len = 4; ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("tel")); fd->type = USER_STRING_TYPE; fd->setLenByCharnum(21); fd->setNullable(true, true); char keyNum = 0; keydef* kd = def->insertKey(tableid, keyNum); keySegment* seg1 = &kd->segments[0]; seg1->fieldNum = 0; seg1->flags.bit8 = true; // extended key type seg1->flags.bit1 = true; // chanageable kd->segmentCount = 1; td = def->tableDefs(tableid); td->primaryKeyNum = keyNum; ++keyNum; kd = def->insertKey(tableid, keyNum); seg1 = &kd->segments[0]; seg1->fieldNum = 2; seg1->flags.bit0 = true; seg1->flags.bit8 = true; seg1->flags.bit1 = true; kd->segmentCount = 1; def->updateTableDef(tableid); if (def->stat() != 0) return showDbdefError(def, _T("user updateTableDef")); return true; } bool createGroupTable(dbdef* def) { short tableid = 2; tabledef t; tabledef* td = &t; td->charsetIndex = mysql::charsetIndex(GetACP()); td->schemaCodePage = CP_UTF8; td->id = tableid; td->setTableName(_T("groups")); td->setFileName(_T("groups")); def->insertTable(td); if (def->stat() != 0) return showDbdefError(def, _T("groups insertTable")); short filedIndex = 0; fielddef* fd = def->insertField(tableid, filedIndex); fd->setName(_T("code")); fd->type = ft_integer; fd->len = 4; ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("name")); fd->type = GROUP_STRING_TYPE; fd->len = 33; char keyNum = 0; keydef* kd = def->insertKey(tableid, keyNum); keySegment* seg1 = &kd->segments[0]; seg1->fieldNum = 0; seg1->flags.bit8 = true; // extended key type seg1->flags.bit1 = true; // chanageable kd->segmentCount = 1; td = def->tableDefs(tableid); td->primaryKeyNum = keyNum; def->updateTableDef(tableid); if (def->stat() != 0) return showDbdefError(def, _T("groups updateTableDef")); return true; } bool createUserExtTable(dbdef* def) { short tableid = 3; tabledef t; tabledef* td = &t; td->charsetIndex = mysql::charsetIndex(GetACP()); td->schemaCodePage = CP_UTF8; td->id = tableid; td->setTableName(_T("extention")); td->setFileName(_T("extention")); def->insertTable(td); if (def->stat() != 0) return showDbdefError(def, _T("extention insertTable")); short filedIndex = 0; fielddef* fd = def->insertField(tableid, filedIndex); fd->setName(_T("id")); fd->type = ft_integer; fd->len = 4; ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("comment")); fd->type = USER_STRING_TYPE; fd->setLenByCharnum(60); ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("blob")); fd->type = BLOB_TYPE; fd->setNullable(true, true); #ifndef USE_PSQL_DATABASE fd->len = 10; ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("binary")); fd->type = BLOB_TYPE; fd->len = 10; #else fd->len = 16000; #endif char keyNum = 0; keydef* kd = def->insertKey(tableid, keyNum); keySegment* seg1 = &kd->segments[0]; seg1->fieldNum = 0; seg1->flags.bit8 = true; // extended key type seg1->flags.bit1 = true; // chanageable kd->segmentCount = 1; td = def->tableDefs(tableid); td->primaryKeyNum = keyNum; def->updateTableDef(tableid); if (def->stat() != 0) return showDbdefError(def, _T("extention updateTableDef")); return true; } bool createCacheTable(dbdef* def) { short tableid = 5; tabledef t; tabledef* td = &t; td->charsetIndex = mysql::charsetIndex(GetACP()); td->schemaCodePage = CP_UTF8; td->id = tableid; td->setTableName(_T("cache")); td->setFileName(_T("cache")); def->insertTable(td); if (def->stat() != 0) return showDbdefError(def, _T("cache insertTable")); short filedIndex = 0; fielddef* fd = def->insertField(tableid, filedIndex); fd->setName(_T("id")); fd->type = ft_autoinc; fd->len = 4; ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("value")); fd->type = GROUP_STRING_TYPE; fd->len = 60000; char keyNum = 0; keydef* kd = def->insertKey(tableid, keyNum); keySegment* seg1 = &kd->segments[0]; seg1->fieldNum = 0; seg1->flags.bit8 = true; // extended key type seg1->flags.bit1 = true; // chanageable kd->segmentCount = 1; td = def->tableDefs(tableid); td->primaryKeyNum = keyNum; def->updateTableDef(tableid); if (def->stat() != 0) return showDbdefError(def, _T("cache updateTableDef")); return true; } bool createBlobOnlyTable(dbdef* def) { short tableid = 4; tabledef t; tabledef* td = &t; td->charsetIndex = mysql::charsetIndex(GetACP()); td->schemaCodePage = CP_UTF8; td->id = tableid; td->setTableName(_T("blobonly")); td->setFileName(_T("blobonly")); def->insertTable(td); if (def->stat() != 0) return showDbdefError(def, _T("blobonly insertTable")); short filedIndex = 0; fielddef* fd = def->insertField(tableid, filedIndex); fd->setName(_T("id")); fd->type = ft_integer; fd->len = 4; ++filedIndex; fd = def->insertField(tableid, filedIndex); fd->setName(_T("binary")); fd->type = BLOB_TYPE; fd->len = 10; char keyNum = 0; keydef* kd = def->insertKey(tableid, keyNum); keySegment* seg1 = &kd->segments[0]; seg1->fieldNum = 0; seg1->flags.bit8 = true; // extended key type seg1->flags.bit1 = true; // chanageable kd->segmentCount = 1; td = def->tableDefs(tableid); td->primaryKeyNum = keyNum; def->updateTableDef(tableid); if (def->stat() != 0) return showDbdefError(def, _T("blobonly updateTableDef")); return true; } void fillBlobField(short fieldNum, int id, table* tb, unsigned char* buf) { for (int j = 0 ; j < 256 ; ++j) buf[j] = (unsigned char)(j + id); tb->setFV(fieldNum, buf, 256); } bool compBlobField(int id, field& fd) { uint_td size; unsigned char* p = (unsigned char*)fd.getBin(size); if (size != 256) return false; for (int j = 0 ; j < 256 ; ++j) { if (p[j] != (unsigned char)(j + id)) return false; } return true; } bool insertData(database_ptr db, int maxId) { _TCHAR tmp[256]; table* tbu = db->openTable(_T("user"), TD_OPEN_NORMAL); if (db->stat()) { showDbError(db.get(), _T("openTable user")); return false; } table* tbg = db->openTable(_T("groups"), TD_OPEN_NORMAL); if (db->stat()) { showDbError(db.get(), _T("openTable groups")); return false; } table* tbe = db->openTable(_T("extention"), TD_OPEN_NORMAL); if (db->stat()) { showDbError(db.get(), _T("openTable extention")); return false; } table* tbb = db->openTable(_T("blobonly"), TD_OPEN_NORMAL); if (db->stat()) { showDbError(db.get(), _T("openTable blobonly")); return false; } dbTransaction trn(db); trn.begin(); tbu->clearBuffer(); for (int i = 1; i <= maxId; ++i) { tbu->setFV((short)0, i); _stprintf_s(tmp, 256, _T("%d user"), i); tbu->setFV(1, tmp); tbu->setFV(_T("group"), ((i - 1) % 5) + 1); tbu->insert(); if (tbu->stat() != 0) return showTableError(tbu, _T("user insert")); } tbg->clearBuffer(); for (int i = 1; i <= 100; ++i) { tbg->setFV((short)0, i); _stprintf_s(tmp, 256, _T("%d group"), i); tbg->setFV(1, tmp); tbg->insert(); if (tbg->stat() != 0) return showTableError(tbg, _T("groups insert")); } unsigned char bin[256]; tbe->clearBuffer(); for (int i = 1; i <= maxId; ++i) { tbe->setFV((short)0, i); _stprintf_s(tmp, 256, _T("%d comment"), i); tbe->setFV(1, tmp); _stprintf_s(tmp, 256, _T("%d blob"), i); tbe->setFV(2, tmp); fillBlobField(3, i, tbe, bin); tbe->insert(); if (tbe->stat() != 0) return showTableError(tbe, _T("extention insert")); } tbb->clearBuffer(); for (int i = 1; i <= 10; ++i) { tbb->setFV((short)0, i); fillBlobField(1, i, tbb, bin); tbb->insert(); if (tbb->stat() != 0) return showTableError(tbb, _T("blobonly insert")); } trn.end(); tbg->release(); tbu->release(); tbe->release(); tbb->release(); return true; } bool checkVersion(database_ptr db) { dbdef* def = db->dbDef(); if (def) { tabledef* td = def->tableDefs(3); if (td) { if (td->fieldCount == 4) { table_ptr tb = openTable(db, _T("extention")); if (tb->recordCount(false) == 20000) return td->fieldDefs[2].isNullable() == true; return false; } } } return false; } int prebuiltData(database_ptr db, const connectParams& param, bool foceCreate, int maxId) { try { if (db->open(param.uri(), TD_OPEN_NORMAL)) { if (foceCreate || !checkVersion(db)) dropDatabase(db); else return 0; }else if (db->stat() == STATUS_INVALID_DATASIZE) { dropDatabase(db); } std::tcout << _T("\nInserting query test data. Please wait... ") << std::flush; createDatabase(db, param); openDatabase(db, param); if (!createUserTable(db->dbDef())) return 1; if (!createGroupTable(db->dbDef())) return 1; if (!createUserExtTable(db->dbDef())) return 1; if (!createBlobOnlyTable(db->dbDef())) return 1; if (!insertData(db, maxId)) return 1; std::tcout << _T("done!") << std::endl; return 0; } catch (bzs::rtl::exception& e) { std::tcout << _T("\n") << *bzs::rtl::getMsg(e) << std::endl; return 1; } }