sevencat 发表于 2012-6-30 09:05:09

esent,c++ 接口实例详解

esent是微軟的一個小型数据库,但不支持sql,支持事务以及其他高级功能。
下面是我辛苦整理出来的例子,应该不夸张的说,市面上很难找到比这个更全的c++代码了,特别一提的是JetIntersectIndexes这个重要的函数,网上似乎没有人说到关键点,包括managed esent
class JetTest
{
public:
    void init()
    {
      JetCreateInstance(&instance, "EsentPerf");

      JetSetSystemParameter(&instance, JET_sesidNil, JET_paramCircularLog, 1, NULL);
      JetSetSystemParameter(&instance, JET_sesidNil, JET_paramLogFileSize, 4*1024, NULL);    // in KB
      JetSetSystemParameter(&instance, JET_sesidNil, JET_paramLogBuffers, 4*1024, NULL);    // in 512-bye units

      JetInit(&instance);
      JetBeginSession(instance, &sesid, 0, 0);
    }
    bool open_db()
    {
      int err=JetAttachDatabase(sesid,"esentperftest.db",0);
      err=JetOpenDatabase(sesid,"esentperftest.db",NULL,&dbid,0);
      if(err!=JET_errSuccess)
      {
            return false;
      }
      JetOpenTable(sesid, dbid, "table", NULL, 0, 0, &tableid);
      get_colid();
      return true;
    }
    bool create_db()
    {
      
      JET_COLUMNDEF columndef = {0};

      JetCreateDatabase(sesid, "esentperftest.db", 0, &dbid, 0);
      JetBeginTransaction(sesid);
      JetCreateTable(sesid, dbid, "table", 0, 100, &tableid);

      columndef.cbStruct = sizeof(columndef);
      columndef.coltyp = JET_coltypCurrency;//64位整数
      JetAddColumn(sesid, tableid, "Key", &columndef, NULL, 0, &columnidKey);

      columndef.coltyp = JET_coltypText;
      columndef.cbMax=10;
      JetAddColumn(sesid, tableid, "Data", &columndef, NULL, 0, &columnidData);

      err=JetCreateIndex(sesid, tableid, "primary", JET_bitIndexPrimary|JET_bitIndexUnique, "+data\0+key\0", 12, 100);
      err=JetCreateIndex(sesid, tableid, "idx_key", 0, "+key\0",6, 100);
      err=JetCreateIndex(sesid, tableid, "idx_data", 0, "+data\0",7,100);
      JetCommitTransaction(sesid, 0);
      get_colid();
      insert();
      return true;
    }

    void get_colid()
    {
      {
            JET_COLUMNDEF col;
            JetGetColumnInfo(sesid,dbid,"table","Key",&col,sizeof(col),JET_ColInfo);
            columnidKey=col.columnid;
      }
      {
            JET_COLUMNDEF col;
            JetGetColumnInfo(sesid,dbid,"table","Data",&col,sizeof(col),JET_ColInfo);
            columnidData=col.columnid;
      }
    }

    void insert()
    {
      JetBeginTransaction(sesid);
      for(__int64 day=20120601;day<20120630;day++)
      {
            for(int i=600000;i<600300;i++)
            {
                JetPrepareUpdate(sesid, tableid, JET_prepInsert);
                char buf;
                int len=sprintf(buf,"SH%d",i);
                JET_SETCOLUMN setcolumns[] =
                {
                  { columnidKey, &day, sizeof(day), 0, 0, 1, JET_errSuccess },
                  { columnidData, buf, len, 0, 0, 1, JET_errSuccess },
                };
                err=JetSetColumns(sesid, tableid, setcolumns, _countof(setcolumns));
                err=JetUpdate(sesid, tableid, NULL, 0, NULL);
            }
      }
      JetCommitTransaction(sesid, 0);
    }

    void select()
    {
      __int64 key;
      unsigned char data={0};
      JET_RETRIEVECOLUMN retcolumns[] =
      {
            { columnidKey, &key, sizeof(key), 0, 0, 0, 1, 0, JET_errSuccess },
            { columnidData, data, sizeof(data), 0, 0, 0, 1, 0, JET_errSuccess },
      };


      JetMove(sesid, tableid, JET_MoveFirst, 0);
      while(true)
      {
            JetBeginTransaction(sesid);
            if(JET_errSuccess==JetRetrieveColumns(sesid, tableid, retcolumns, _countof(retcolumns)))
            {
                printf("%I64d    %s\n",key,data);
            }

            JetCommitTransaction(sesid, 0);
            if(JET_errSuccess != JetMove(sesid, tableid, JET_MoveNext, 0))
                break;
      }
    }

    void search1()
    {
      __int64 key=0;
      char data={0};
      int datalen=sprintf(data,"SH600002");

      JetBeginTransaction(sesid);
      err=JetSetCurrentIndex(sesid,tableid,NULL);
      err=JetMakeKey(sesid, tableid, data, datalen, JET_bitNewKey);
      err=JetMakeKey(sesid, tableid, &key, sizeof(key), 0);
      err=JetSeek(sesid, tableid, JET_bitSeekGE);
      if((err==JET_errSuccess)||(err==JET_wrnSeekNotEqual))
      {
            key=0;
            memset(data,0,sizeof(data));
            JET_RETRIEVECOLUMN retcolumns[] =
            {
                { columnidKey, &key, sizeof(key), 0, 0, 0, 1, 0, JET_errSuccess },
                { columnidData, data, sizeof(data), 0, 0, 0, 1, 0, JET_errSuccess },
            };
            JetRetrieveColumns(sesid, tableid, retcolumns, _countof(retcolumns));
      }
      JetCommitTransaction(sesid, 0);
      printf("we find it!!!\n");
    }

    void search2()
    {
      __int64 key=12;
      char data={0};
      int datalen=sprintf(data,"%I64d",0);

      JetBeginTransaction(sesid);
      err=JetSetCurrentIndex(sesid,tableid,NULL);
      err=JetMakeKey(sesid, tableid, &key, sizeof(key), JET_bitNewKey);
      err=JetMakeKey(sesid, tableid, data, datalen, 0);
      err=JetSeek(sesid, tableid, JET_bitSeekGT);

      key=24;
      err=JetMakeKey(sesid, tableid, &key, sizeof(key), JET_bitNewKey);
      err=JetMakeKey(sesid, tableid, data, datalen, 0);
      //err=JetSeek(sesid, tableid, JET_bitSeekLT);

      err=JetSetIndexRange(sesid,tableid,JET_bitRangeInclusive|JET_bitRangeUpperLimit);

      JET_RETRIEVECOLUMN retcolumns[] =
      {
            { columnidKey, &key, sizeof(key), 0, 0, 0, 1, 0, JET_errSuccess },
            { columnidData, data, sizeof(data), 0, 0, 0, 1, 0, JET_errSuccess },
      };


      while(true)
      {
            JetBeginTransaction(sesid);
            JetRetrieveColumns(sesid, tableid, retcolumns, _countof(retcolumns));
            JetCommitTransaction(sesid, 0);
            if(JET_errSuccess != JetMove(sesid, tableid, JET_MoveNext, 0))
                break;
      }
    }

    void search3()
    {
      JET_TABLEID newtable;
      err=JetOpenTable(sesid, dbid, "table", NULL, 0, 0, &newtable);
      {
            int curtable=newtable;
            __int64 key=20120602;
            err=JetSetCurrentIndex(sesid,curtable,"idx_key");
            err=JetMakeKey(sesid,curtable,&key,sizeof(key),JET_bitNewKey);
            err=JetSeek(sesid, curtable, JET_bitSeekGE);
            key=20120612;
            err=JetMakeKey(sesid,curtable,&key,sizeof(key),JET_bitNewKey);
            err=JetSetIndexRange(sesid,curtable,JET_bitRangeInclusive|JET_bitRangeUpperLimit);
      }

      
      //err=JetDupCursor(sesid,tableid,&newtable,0);

      {
            int curtable=tableid;
            char data={0};
            int datalen=sprintf(data,"SH600002");
            err=JetSetCurrentIndex(sesid,curtable,"idx_data");
            err=JetMakeKey(sesid,curtable,data,datalen,JET_bitNewKey);
            err=JetSeek(sesid, curtable, JET_bitSeekGE);
            datalen=sprintf(data,"SH600004");
            err=JetMakeKey(sesid,curtable,data,datalen,JET_bitNewKey);
            err=JetSetIndexRange(sesid,curtable,JET_bitRangeInclusive|JET_bitRangeUpperLimit);
      }

      JET_INDEXRANGE ir;
      memset(ir,0,sizeof(ir));
      ir.cbStruct=sizeof(JET_INDEXRANGE);
      ir.tableid=tableid;
      ir.grbit=JET_bitRecordInIndex;
      ir.cbStruct=sizeof(JET_INDEXRANGE);
      ir.tableid=newtable;
      ir.grbit=JET_bitRecordInIndex;

      JET_RECORDLIST recs;
      memset(&recs,0,sizeof(recs));
      recs.cbStruct=sizeof(recs);
      err=JetIntersectIndexes(sesid,ir,2,&recs,0);


      __int64 key=12;
      char data={0};
      JET_RETRIEVECOLUMN retcolumns[] =
      {
            { columnidKey, &key, sizeof(key), 0, 0, 0, 1, 0, JET_errSuccess },
            { columnidData, data, sizeof(data), 0, 0, 0, 1, 0, JET_errSuccess },
      };

      err=JetMove(sesid, recs.tableid, JET_MoveFirst,0);
      while(err==JET_errSuccess)
      {
            char buf;
            unsigned long actlen=sizeof(buf);
            err=JetRetrieveColumn(sesid,recs.tableid,recs.columnidBookmark,buf,sizeof(buf),&actlen,0,NULL);
            printf("%I64d,%s\n",key,data);
            err=JetGotoBookmark(sesid,tableid,buf,actlen);
            err=JetRetrieveColumns(sesid, tableid, retcolumns, _countof(retcolumns));
            err=JetMove(sesid, recs.tableid, JET_MoveNext,0);
      }
   
    }
public:

    JET_INSTANCE instance;
    JET_SESID sesid;
    JET_DBID dbid;
    JET_TABLEID tableid;
   
    JET_COLUMNID columnidKey;
    JET_COLUMNID columnidData;

    int err;
};

sevencat 发表于 2012-6-30 09:12:02

这个东东的优势在于性能,我想在i3机器上一秒插入1万条数据应该不是什么难事情。

sevencat 发表于 2012-6-30 09:14:46

最后一个函数search3为多个索引联合查询。

iq50 发表于 2012-7-5 16:46:29

无私的奉献啊,这东西就是太偏门了,不过我也讨厌SQL哈哈

sevencat 发表于 2012-7-13 10:36:38

实测结果性能比sqlite强多了。
页: [1]
查看完整版本: esent,c++ 接口实例详解