test_bdb.cpp
来自「ncbi源码」· C++ 代码 · 共 2,043 行 · 第 1/3 页
CPP
2,043 行
/* * =========================================================================== * PRODUCTION $Log: test_bdb.cpp,v $ * PRODUCTION Revision 1000.5 2004/06/01 18:37:53 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.46 * PRODUCTION * =========================================================================== *//* $Id: test_bdb.cpp,v 1000.5 2004/06/01 18:37:53 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Anatoliy Kuznetsov * * File Description: Test application for NCBI Berkeley DB library (BDB) * */#include <ncbi_pch.hpp>#include <corelib/ncbiapp.hpp>#include <corelib/ncbiargs.hpp>#include <corelib/ncbifile.hpp>#include <corelib/ncbitime.hpp>#include <stdio.h>#include <bdb/bdb_expt.hpp>#include <bdb/bdb_types.hpp>#include <bdb/bdb_file.hpp>#include <bdb/bdb_env.hpp>#include <bdb/bdb_cursor.hpp>#include <bdb/bdb_blob.hpp>#include <bdb/bdb_map.hpp>#include <bdb/bdb_blobcache.hpp>#include <bdb/bdb_filedump.hpp>#include <bdb/bdb_trans.hpp>#include <bdb/bdb_query.hpp>#include <bdb/bdb_query_parser.hpp>#include <test/test_assert.h> /* This header must go last */USING_NCBI_SCOPE;static const char* s_TestStrTempl = "Test str %i";static const char* s_StrKeyTempl = "%i test key %i";////////////////////////////////// Test functions, classes, etc.////////////////////////////////////////////////////////////////////// // Structure implements simple database table with integer id primary key////struct TestDBF1 : public CBDB_IdFile{ CBDB_FieldInt4 idata; CBDB_FieldString str; CBDB_FieldInt4 i2; CBDB_FieldInt2 ishort; TestDBF1() { BindData("idata", &idata); BindData("str", &str, 256); BindData("i2", &i2); BindData("ishort", &ishort); }};struct TestDBF1L : public CBDB_IdFile{ CBDB_FieldInt4 idata; CBDB_FieldLString str; CBDB_FieldInt4 i2; CBDB_FieldInt2 ishort; TestDBF1L() { BindData("idata", &idata); BindData("str", &str, 256); BindData("i2", &i2); BindData("ishort", &ishort); SetLegacyStringsCheck(true); }};// Utility function to check record consistency template<class T>void ValidateRecord(const T& dbf1, unsigned int id){ char buf[256]; sprintf(buf, s_TestStrTempl, id); int idata1 = dbf1.idata; unsigned int id_key = dbf1.IdKey; string s; s = dbf1.str; int i21 = dbf1.i2; assert(s == string(buf)); assert(id_key == id); assert(idata1 == (int)(400 + id)); assert(i21 == (int)(id + 3)); }const char* s_TestFileName = "testbase.db";const char* s_TestFileName2= "testbase2.db";const char* s_TestFileName3= "testbase3.db";const char* s_db_map1 = "i2s.db";const char* s_db_map2 = "ii2s.db";const unsigned int s_RecsInTable = 100;//////////////////////////////////////////////////////////////////// // Structure implements simple database table with case insensitive string // as a primary key////struct TestDBF2 : public CBDB_File{ CBDB_FieldStringCase str_key; CBDB_FieldInt4 idata; CBDB_FieldString str; CBDB_FieldInt4 i2; TestDBF2() { BindKey("strkey", &str_key, 256); BindData("idata", &idata); BindData("str", &str, 256); BindData("i2", &i2); }};// Utility function to check record consistency void ValidateRecord(const TestDBF2& dbf2, unsigned i){ char buf[256]; sprintf(buf, s_StrKeyTempl, i, i); string s = (const char*)dbf2.str_key; assert(s == string(buf)); assert(dbf2.idata == (int)(400+i)); sprintf(buf, s_TestStrTempl, i); s = (const char*)dbf2.str; assert(s == string(buf)); assert((int)dbf2.i2 == (int)(i+3));}struct TestDBF3 : public CBDB_File{ CBDB_FieldInt4 ikey; CBDB_FieldInt4 idata; TestDBF3() { BindKey("ikey", &ikey); BindData("idata", &idata); }};////////////////////////////////////////////////////////////////////// // BDB transaction test////staticvoid s_TEST_BDB_Transaction(void){ cout << "======== Transactions test." << endl; CBDB_Env env; env.OpenWithTrans("."); TestDBF3 dbf3; dbf3.SetEnv(env); dbf3.Open("trans_test.db", CBDB_File::eReadWriteCreate); cout << dbf3.CountRecs() << endl; CBDB_Transaction trans(env); dbf3.SetTransaction(&trans); dbf3.ikey = 10; dbf3.idata = 11; dbf3.Insert(); dbf3.ikey = 12; dbf3.idata = 13; dbf3.Insert(); trans.Commit(); dbf3.ikey = 10; EBDB_ErrCode ret = dbf3.Fetch(); assert (ret == eBDB_Ok); int idata = dbf3.idata; assert(idata == 11); dbf3.ikey = 10; dbf3.idata = 20; dbf3.UpdateInsert(); ret = dbf3.Fetch(); assert (ret == eBDB_Ok); idata = dbf3.idata; assert(idata == 20); dbf3.ikey = 12; ret = dbf3.Fetch(); assert (ret == eBDB_Ok); idata = dbf3.idata; assert(idata == 13); trans.Abort(); dbf3.SetTransaction(0); dbf3.ikey = 10; ret = dbf3.Fetch(); assert (ret == eBDB_Ok); idata = dbf3.idata; assert(idata == 11); cout << "======== Transactions test ok." << endl;}////////////////////////////////////////////////////////////////////// // BDB types test////static void s_TEST_BDB_Types(void){ cout << "======== BDB types test." << endl; TestDBF1 dbf1; cout << "======== BDB types test ok." << endl;}////////////////////////////////////////////////////////////////////// // BDB Id table fill test////static void s_IdTableFill(TestDBF1& dbf, unsigned int records){ for (unsigned int i = 1; i < records; ++i) { char buf[256]; sprintf(buf, s_TestStrTempl, i); dbf.IdKey = i; dbf.idata = 400+i; dbf.str = buf; dbf.i2.Set(i+3); int i2 = dbf.i2; assert (i2 == (int)(i+3)); assert(!dbf.idata.IsNull()); EBDB_ErrCode err = dbf.Insert(); assert(err == eBDB_Ok); assert(dbf.idata.IsNull()); }}static void s_TEST_BDB_IdTable_Fill(void){ cout << "======== Id table filling test." << endl; CBDB_Env env; env.OpenWithLocks(0); env.OpenErrFile("err_test.txt"); TestDBF1 dbf1; dbf1.SetEnv(env); dbf1.SetPageSize(32 * 1024); dbf1.SetCacheSize(5 * (1024 * 1024)); dbf1.Open(s_TestFileName, CBDB_File::eCreate); assert(dbf1.idata.IsNull()); // Fill the table unsigned i; s_IdTableFill(dbf1, s_RecsInTable); // Trying to put duplicate record dbf1.IdKey = 1; dbf1.idata = 400 + 1; dbf1.str = "test"; EBDB_ErrCode err = dbf1.Insert(); assert(err == eBDB_KeyDup); cout << "Table " << s_TestFileName << " loaded ok. Checking consistency." << endl; // Read the table check if all records are in place dbf1.Reopen(CBDB_File::eReadOnly); for (i = 1; i < s_RecsInTable; ++i) { dbf1.IdKey = i; EBDB_ErrCode ret = dbf1.Fetch(); assert (ret == eBDB_Ok); ValidateRecord(dbf1, i); } // for {{ TestDBF1 dbf11; dbf11.Attach(dbf1); for (i = 1; i < s_RecsInTable; ++i) { dbf11.IdKey = i; EBDB_ErrCode ret = dbf11.Fetch(); assert (ret == eBDB_Ok); ValidateRecord(dbf11, i); // Checking that attached buffer doesn't change status of the main one dbf1.IdKey = 1; ret = dbf1.Fetch(); assert (ret == eBDB_Ok); ValidateRecord(dbf1, 1); ValidateRecord(dbf11, i); } // for }} {{ TestDBF1L dbf11; dbf11.Open(s_TestFileName, CBDB_File::eReadWrite); for (i = 1; i < s_RecsInTable; ++i) { dbf11.IdKey = i; EBDB_ErrCode ret = dbf11.Fetch(); assert (ret == eBDB_Ok); ValidateRecord(dbf11, i); } // for string s = "123"; s.append(1, (char)0); s.append("123"); cout << "(" << s << ")" << s.length() << endl; dbf11.IdKey = 1000; dbf11.idata = 1000; dbf11.str = s; dbf11.Insert(); dbf11.IdKey = 1000; EBDB_ErrCode ret = dbf11.Fetch(); assert (ret == eBDB_Ok); string s2 = dbf11.str; string s3 = dbf11.str.GetString(); size_t l2 = s2.length(); size_t l3 = s3.length(); assert(s3 == s); assert(s2 == s); assert(l2 == l3); // Dumping the database to screen CBDB_FileDumper dump; dump.Dump(cout, dbf11); }} cout << "======== Id table filling test ok." << endl;}static void s_TEST_BDB_IdTable_FillStress(void){ cout << "======== Id table filling stress test." << endl; CBDB_Env env; env.SetCacheSize(150 * (1024 * 1024)); env.OpenWithLocks(0); TestDBF1 dbf1; dbf1.SetEnv(env); dbf1.Open(s_TestFileName, CBDB_File::eCreate); assert(dbf1.idata.IsNull()); // Fill the table unsigned i; const unsigned int recs = 1000000; s_IdTableFill(dbf1, recs); cout << "Table loaded..." << endl; // Read the table check if all records are in place dbf1.Reopen(CBDB_File::eReadOnly); for (i = 1; i < recs; ++i) { dbf1.IdKey = i; EBDB_ErrCode ret = dbf1.Fetch(); assert (ret == eBDB_Ok); ValidateRecord(dbf1, i); } // for cout << "Check 1 complete" << endl; dbf1.Reopen(CBDB_File::eReadOnly); for (i = 1; i < recs; ++i) { {{ CBDB_FileCursor cur(dbf1); cur.SetCondition(CBDB_FileCursor::eEQ); cur.From << i; EBDB_ErrCode ret = cur.FetchFirst(); assert (ret == eBDB_Ok); ValidateRecord(dbf1, i); }} } // for cout << "======== Id table stress filling test ok." << endl;}class CTestScanner : public CBDB_FileScanner{public: CTestScanner(CBDB_File& db_file) : CBDB_FileScanner(db_file) {} virtual EScanAction OnRecordFound() { return eContinue; }protected: };static void s_TEST_BDB_Query(void){ bool bres; cout << "======== Query test." << endl; TestDBF1 dbf1; dbf1.Open(s_TestFileName, CBDB_File::eReadOnly); dbf1.IdKey = 1; dbf1.Fetch(); CTestScanner scanner(dbf1); CBDB_Query query; {{ const char* ch = " test"; CBDB_Query query; BDB_PrintQueryTree(cout, query); BDB_ParseQuery(ch, &query); BDB_PrintQueryTree(cout, query); }} {{ const char* ch = " '2' And ((name3 OR 1) & name3)"; CBDB_Query query; BDB_ParseQuery(ch, &query); BDB_PrintQueryTree(cout, query); }} // Testing the query evaluation logic // // "1" == "2" => false {{ CBDB_Query::TQueryClause* eq_node = CBDB_Query::NewOperatorNode(CBDB_QueryNode::eEQ, "1", "2"); query.SetQueryClause(eq_node); bres = scanner.StaticEvaluate(query); assert(!bres); BDB_PrintQueryTree(cout, query); }} {{ const char* ch = "'1' = 2"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(!bres); }} {{ const char* ch = "not '1' = 2"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); cout << endl; BDB_PrintQueryTree(cout, query); assert(bres); }} {{ const char* ch = "'1' != 2"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "'1' <> 2"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "'1' < 2"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "'1' <= 1"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "'1' >= 1"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "'2' > 1"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} // "2" == "2" => true {{ CBDB_Query::TQueryClause* eq_node = CBDB_Query::NewOperatorNode(CBDB_QueryNode::eEQ, "2", "2"); query.SetQueryClause(eq_node); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "2 = 2"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} // ("1" == "1" AND "2" == "2") => true {{ CBDB_Query::TQueryClause* eq_node1 = CBDB_Query::NewOperatorNode(CBDB_QueryNode::eEQ, "2", "2"); CBDB_Query::TQueryClause* eq_node2 = CBDB_Query::NewOperatorNode(CBDB_QueryNode::eEQ, "1", "1"); CBDB_Query::TQueryClause* and_node = new CBDB_Query::TQueryClause(CBDB_QueryNode::eAnd); and_node->AddNode(eq_node1); and_node->AddNode(eq_node2); query.SetQueryClause(and_node); bres = scanner.StaticEvaluate(query); assert(bres); }} {{ const char* ch = "(1=1 AND 2=2)"; BDB_ParseQuery(ch, &query); bres = scanner.StaticEvaluate(query); assert(bres); }} // ("1" == "1" AND "2" == "0") => false {{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?