我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。
源码指引:github源码指引_初级代码游戏的博客-CSDN博客
本专题:基于共享内存的内存数据库_初级代码游戏的博客-CSDN博客
从这里开始顺序阅读:一个基于共享内存的内存数据库:1 介绍-CSDN博客
本文介绍Demo代码,Demo代码来自自带的系统管理程序。
目录
一、创建
CShmDB::getInstPtr()->GetCShmActiveObjects()->CreateShm();
系统范围内只需要创建一次。 如果系统重启则需要再次重新创建。
很显然,支持基础共享内存的所有公共管理操作。比如为了解决共享内存分块过多,可以先执行导出到文件,再执行从文件加载。
二、连接
CShmDB::getInstPtr()->GetCShmActiveObjects()->Attach(false);
参数是是否只读,因为一般都要读写,所以用false。
每个程序都需要执行一次,如果fork子进程,子进程不需要重新连接(这是操作系统的特征)。
三、创建表和索引
3.1 代码
pDB= CShmDB::getInstPtr();
vector<pair<string,COLUMN_TYPE> > cols;
//验证错误的配置
cols.push_back(pair<string,COLUMN_TYPE>("A",COLUMN_TYPE_LONG));
cols.push_back(pair<string,COLUMN_TYPE>("A",COLUMN_TYPE_LONG));
cols.push_back(pair<string,COLUMN_TYPE>("C",COLUMN_TYPE_LONG));
pDB->CreateTable("test",cols,"AA");
//正确的配置
cols.clear();
cols.push_back(pair<string,COLUMN_TYPE>("A",COLUMN_TYPE_LONG));
cols.push_back(pair<string,COLUMN_TYPE>("B",COLUMN_TYPE_DOUBLE));
cols.push_back(pair<string,COLUMN_TYPE>("C",COLUMN_TYPE_STRING_POOL));
pDB->CreateTable("test",cols,"A");
pDB->CreateIndex("test","INDEX_B","B");
pDB->CreateIndex("test","INDEX_C","C");
pDB->CreateIndex("test","INDEX_CBA","C,B,A");
CShmDB::CRecordSet rs;
if(!rs.Open(true,"test","PK"))
{
return false;
}
long i;
char buf[2048];
for(i=0;i<10;++i)
{
if(!rs.AddNew())
{
rs.Close();
return false;
}
rs.SetFieldValue((long)0,i);
rs.SetFieldValue(1,10-i);
sprintf(buf,"%c",'z'-i);
rs.SetFieldValue(2,buf);
if(!rs.Update())
{
rs.Close();
return false;
}
}
rs.Close();
以上代码手工创建了一张表(第一次创建因为列重复而失败),然后添加了一些数据。对数据的操作类似MFC的ODBC的记录集操作(实际就是参照这个设计的)。
3.2 执行结果
3.2.1 表和列
3.2.2 索引
3.2.3 部分数据
INDEX_B
INDEX_CBA
PK
四、查询所有表
pDB= CShmDB::getInstPtr();
set<string > tables;
set<string >::const_iterator it_tables;
mystd::CHtmlDoc::CHtmlTable2 htmltable;
char buf[2048];
long i;
long colnum=10;
pDB->GetAllTableName(tables);
htmltable.AddCol("");
for(i=0;i<colnum;++i)
{
sprintf(buf,"%ld",i+1);
htmltable.AddCol(buf);
}
long line=0;
for(i=0,it_tables=tables.begin();it_tables!=tables.end();++i,++it_tables)
{
if(0==i%colnum)
{
line=htmltable.AddLine();
htmltable.SetData(line,0,line+1);
}
htmltable.SetData(line,i%colnum+1,*it_tables);
}
thelog<<endl<<"table count : "<<tables.size()<<endl<<htmltable.MakeTextTable()<<endi;
关键的只是“GetAllTableName”这个一个函数调用。
输出:
此输出并非对应上一节的代码的结果,而是对应另一项测试代码。
五、查询表的列
代码承上节。
查询列没有独立的函数,而是通过记录集来返回(当然是可以增加这样一个函数的)。
string table;
table=UIInput("请输入表名(回车=退出)","");
if(table.size()==0)return true;
CShmDB::CRecordSet rs;
if(!rs.Open(false,table.c_str(),"PK"))
{
thelog<<"打开表出错 "<<table<<ende;
return false;
}
htmltable.Clear();
htmltable.AddCol("序号");
htmltable.AddCol("列名");
htmltable.AddCol("类型");
for(i=0;i<rs.GetColumnCount();++i)
{
line=htmltable.AddLine();
htmltable.SetData(line,0,i);
htmltable.SetData(line,1,rs.GetColumnName(i));
htmltable.SetData(line,2,rs.GetColumnType(i));
}
thelog<<endl<<htmltable.MakeTextTable()<<endi;
rs.Close();
输出结果:
六、查询表的索引
代码承上节。
pDB->GetTableAllIndex(table.c_str(),indexs);
htmltable.Clear();
htmltable.AddCol("索引");
htmltable.AddCol("序号");
htmltable.AddCol("列名");
for(it_indexs=indexs.begin();it_indexs!=indexs.end();++it_indexs)
{
vector<string > cols;
if(!pDB->GetIndexColumns(table.c_str(),it_indexs->c_str(),cols))
{
thelog<<"获得索引定义出错 "<<table<<" "<<*it_indexs<<ende;
return false;
}
for(i=0;i<cols.size();++i)
{
line=htmltable.AddLine();
htmltable.SetData(line,0,*it_indexs);
htmltable.SetData(line,1,i);
htmltable.SetData(line,2,cols[i]);
}
}
thelog<<endl<<"index count : "<<indexs.size()<<endl<<htmltable.MakeTextTable()<<endi;
关键的只是“GetIndexColumns”这一个函数。
输出结果:
(未完待续)