.net下BerkeleyDB操作封装C#版(附单元测试)

using System;

using System.Collections.Generic;

using
System.IO;

using System.Linq;

using
System.Runtime.Serialization.Formatters.Binary;

using
System.Text;

using BerkeleyDb;

using Component;

namespace
ToolManager
{
   public class BDBRecord
  
{
       public object Key { get; set;
}
       public string Value { get; set;
}
   }    /**//// <summary>
  
/// BDB数据库操作类库
   /// </summary>
   public class
BDBHelper
   {

       private
string DBFilePath { get; set; }
       private
DBStoreType DBType { get; set; }
       public
enum DBStoreType : byte
      
{
          
Auto=1,
          
Queue,
          
Hash
      
}
       [Obsolete("该构造函数已废弃
,请使用BDBHelper(string dbfilePath)")]
      
public BDBHelper()
      
{
      
}

       public BDBHelper(string
dbfilePath)
      
{
          
this.DBFilePath = dbfilePath;
      
}
       [Obsolete("该构造函数已废弃
,请使用BDBHelper(string dbfilePath)")]
      
public BDBHelper(string dbfilePath, DBStoreType
type)
      
{
          
this.DBFilePath =
dbfilePath;
          
this.DBType = type;
      
}
       public BDBRecord
FindOne()
      
{
           return
this.FindOne(null);
      
}
       public BDBRecord
FindOne(Func<object, string, bool>
predicate)
      
{
          
//Dictionary<string, object> dict = new Dictionary<string,
object>();
          
try
          
{
              
Queue格式#region
Queue格式
              
//if (this.DBType ==
DBStoreType.Queue)
              
//{
              
using (Db db = new
Db(DbCreateFlags.None))
              
{
                  
db.RecLen =
5000;
                  
db.RecPad =
‘.‘;
                  
DbQueue file = (DbQueue)db.Open(null, this.DBFilePath, null, DbType.Queue,
Db.OpenFlags.Create,
0);
                  
using (DbQueueCursor cursor = file.OpenCursor(null,
DbFileCursor.CreateFlags.None))
                  
{
                      
foreach (KeyDataPair kvp in
cursor)
                      
{
                          
BinaryFormatter bf = new
BinaryFormatter();
                          
MemoryStream stream = new
MemoryStream();
                          
stream.Write(kvp.Data.Buffer, 0,
kvp.Data.Size);
                          
stream.Seek(0,
SeekOrigin.Begin);
                          
string k = BitConverter.ToInt32(kvp.Key.Buffer,
0).ToString();
                          
object v =
bf.Deserialize(stream);
                          
if (predicate ==
null)
                          
{
                              
return new BDBRecord() { Key = v, Value = k
};
                          
}
                          
else if (predicate(v,
k))
                          
{
                              
return new BDBRecord() { Key = v, Value = k
};
                          
}
                      
}
                  
}
              
}
              
//}
              
#endregion
          
}
           catch
(Exception ex)
          
{
              
Hash格式#region
Hash格式
              
//else
if(this.DBType==DBStoreType.Hash)
              
//{
              
//遍历数据
              
using (Db db = new
Db(DbCreateFlags.None))
              
{
                  
//这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
                  
//Db.OpenFlags.Truncate会清空数据库
                  
DbHash dbf = (DbHash)db.Open(null, this.DBFilePath, null,
DbType.Hash,
       Db.OpenFlags.ThreadSafe,
0);

                  
using (DbHashCursor cursor = dbf.OpenCursor(null,
DbFileCursor.CreateFlags.None))
                  
{
                      
foreach (KeyDataPair kvp in
cursor)
                      
{
                          
BinaryFormatter bf = new
BinaryFormatter();
                          
MemoryStream stream = new
MemoryStream();
                          
stream.Write(kvp.Data.Buffer, 0,
kvp.Data.Size);
                          
stream.Seek(0,
SeekOrigin.Begin);
                          
string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0,
kvp.Key.Size);
                          
object v =
bf.Deserialize(stream);
                          
if (predicate ==
null)
                          
{
                              
return new BDBRecord() { Key = v, Value = k
};
                          
}
                          
else if (predicate(v,
k))
                          
{
                              
return new BDBRecord() { Key = v, Value = k
};
                          
}
                      
}
                  
}
              
}
              
#endregion
              
//}
          
}
           //return
dict;
           return
null;
      
}
       public Dictionary<object,
string> FindAll(Func<object, string, bool>
predicate)
      
{

          
Dictionary<object, string> dict = new Dictionary<object,
string>();
          
try
          
{
              
Queue格式#region
Queue格式
              
//if (this.DBType ==
DBStoreType.Queue)
              
//{
              
using (Db db = new
Db(DbCreateFlags.None))
              
{
                  
db.RecLen =
5000;
                  
db.RecPad =
‘.‘;
                  
DbQueue file = (DbQueue)db.Open(null, this.DBFilePath, null, DbType.Queue,
Db.OpenFlags.Create,
0);
                  
using (DbQueueCursor cursor = file.OpenCursor(null,
DbFileCursor.CreateFlags.None))
                  
{
                      
foreach (KeyDataPair kvp in
cursor)
                      
{
                          
_Do2(kvp, predicate,
dict);
                      
}
                  
}
              
}
              
//}
              
#endregion
          
}
           catch
(Exception ex)
          
{
              
Hash格式#region
Hash格式
              
//else
if(this.DBType==DBStoreType.Hash)
              
//{
              
//遍历数据
              
using (Db db = new
Db(DbCreateFlags.None))
              
{
                  
//这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
                  
//Db.OpenFlags.Truncate会清空数据库
                  
DbHash dbf = (DbHash)db.Open(null, this.DBFilePath, null,
DbType.Hash,
       Db.OpenFlags.ThreadSafe,
0);

                  
using (DbHashCursor cursor = dbf.OpenCursor(null,
DbFileCursor.CreateFlags.None))
                  
{
                      
foreach (KeyDataPair kdp in
cursor)
                      
{
                          
_Do(kdp, predicate,
dict);
                      
}
                  
}
              
}
              
#endregion
              
//}
          
}
           return
dict;
      
}
       public Dictionary<object,
string> FindAll()
      
{
           //either below
works fine
          
//return this.FindAll((s, o) =>
true);
           return
this.FindAll(null);
      
}
       private static void _Do(KeyDataPair
kvp, Func<object, string, bool> predicate, Dictionary<object,
string> result)
      
{
          
BinaryFormatter bf = new
BinaryFormatter();
          
MemoryStream stream = new
MemoryStream();
          
stream.Write(kvp.Data.Buffer, 0,
kvp.Data.Size);
          
stream.Seek(0,
SeekOrigin.Begin);
          
string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0,
kvp.Key.Size);
          
object v =
bf.Deserialize(stream);
          
if (predicate ==
null)
          
{
              
result.Add(v,
k);
          
}
           else if
(predicate(v,
k))
          
{
              
result.Add(v,
k);
          
}
      
}
       private static void _Do2(KeyDataPair
kvp, Func<object, string, bool> predicate, Dictionary<object,
string> result)
      
{
          
BinaryFormatter bf = new
BinaryFormatter();
          
MemoryStream stream = new
MemoryStream();
          
stream.Write(kvp.Data.Buffer, 0,
kvp.Data.Size);
          
stream.Seek(0,
SeekOrigin.Begin);
          
string k = BitConverter.ToInt32(kvp.Key.Buffer,
0).ToString();
          
object v =
bf.Deserialize(stream);
          
if (predicate ==
null)
          
{
              
result.Add(v,
k);
          
}
           else if
(predicate(v,
k))
          
{
              
result.Add(v,
k);
          
}
      
}
       /**////
<summary>
       ///
更新数据库中的数据
       ///
</summary>
       /// <param
name="predicate">execute
condition</param>
       /// <param
name="isMatchOnlyOnce">is match only
once</param>
       ///
<returns>effect
records</returns>
       public int
UpdateInQueueMode(Func<int, object, bool> predicate, object value,bool
isMatchOnlyOnce)
      
{
               
int count =
0;
               
if (predicate ==
null)
                   
return
0;
             
//遍历数据
              
using (Db db = new
Db(DbCreateFlags.None))
              
{
                  
db.RecLen =
5000;
                  
db.RecPad =
‘.‘;
                  
//这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
                  
//Db.OpenFlags.Truncate会清空数据库
                  
DbQueue dbf = (DbQueue)db.Open(null, this.DBFilePath, null,
DbType.Queue,
      
Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create,
0);

                  
using (DbQueueCursor cursor = dbf.OpenCursor(null,
DbFileCursor.CreateFlags.None))
                  
{
                      
BinaryFormatter bf = new
BinaryFormatter();
                      
MemoryStream stream = new
MemoryStream();
                      
foreach (KeyDataPair kdp in
cursor)
                      
{
                          
int k = BitConverter.ToInt32(kdp.Key.Buffer,
0);
                          
Console.WriteLine("k={0}",
k.ToString());
                          
stream.SetLength(0);
                          
stream.Position =
0;
                          
stream.Write(kdp.Data.Buffer, 0,
kdp.Data.Size);
                          
stream.Seek(0,
SeekOrigin.Begin);
                          
object v =
bf.Deserialize(stream);
                          
if(predicate(k,v))
                          
{
                              
count++;
                              
//string d = Encoding.UTF8.GetString(kdp.Data.Buffer, 0,
kdp.Data.Size);
                              
//如何读取Queue类型的主键值

                              
//Console.WriteLine("{0},{1}", p2.State,
p2.Os);
                              
//p2.Os =
"changed";
                              
//stream = new
MemoryStream();
                              
stream.Position =
0;
                              
stream.SetLength(0);
                              
bf.Serialize(stream,
value);
                              
DbEntry data =
DbEntry.InOut(stream.ToArray());
                              
cursor.Put(ref
data);
                              
if
(isMatchOnlyOnce)
                              
{
                                  
stream.Close();
                                  
return
count;
                              
}
                          
}
                      
}
                          
stream.Close();
                  
}
          
}
           return
count;
      
}

       public void
CreateInQueueMode(object value)
      
{
           Db PC = new
Db(DbCreateFlags.None);
          
PC.RecLen =
5000;
           PC.RecPad
= ‘.‘;
           DbQueue
file = (DbQueue)PC.Open(null, this.DBFilePath, null, DbType.Queue,
Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe,
0);
          
//CreateSecondaryDB(file,"Id.PCs.s",new
DbFile.KeyGeneratorFcn(Common.Id));
          
//CreateSecondaryDB(file, "Id.PCs.s", new
DbFile.KeyGeneratorFcn(Common.Id));
          
//由于数据量不是很大,不考虑使用二级数据库,直接使用游标操作,降低复杂度
          
//首先遍历数据库看有没有已经存在,如果没有,则添加一个,如果有,改变其状态
          
BinaryFormatter bf = new
BinaryFormatter();
          
MemoryStream stream= new
MemoryStream();
          
bf.Serialize(stream,
value);
           DbEntry
k = DbEntry.Out(new
byte[1024]);
          
DbEntry data =
DbEntry.InOut(stream.ToArray());
          
file.Append(null, ref k, ref
data);
          
stream.Close();
          
file.Sync();
          
PC.Close();
      
}
       public int
DeleteInQueueMode(Func<int, object, bool> predicate,bool
isMatchOnlyOnce)
      
{
           int count =
0;
           if (predicate
==
null)
              
return 0;
          
//遍历数据
           using (Db
db = new
Db(DbCreateFlags.None))
          
{
              
db.RecLen =
5000;
              
db.RecPad =
‘.‘;
              
//这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
              
//Db.OpenFlags.Truncate会清空数据库
              
DbQueue dbf = (DbQueue)db.Open(null, this.DBFilePath, null,
DbType.Queue,
   Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create,
0);

              
using (DbQueueCursor cursor = dbf.OpenCursor(null,
DbFileCursor.CreateFlags.None))
              
{
                  
BinaryFormatter bf = new
BinaryFormatter();
                  
MemoryStream stream = new
MemoryStream();
                  
foreach (KeyDataPair kdp in
cursor)
                  
{
                      
int k = BitConverter.ToInt32(kdp.Key.Buffer,
0);
                      
Console.WriteLine("k={0}",
k.ToString());
                      
stream.SetLength(0);
                      
stream.Position =
0;
                      
stream.Write(kdp.Data.Buffer, 0,
kdp.Data.Size);
                      
stream.Seek(0,
SeekOrigin.Begin);
                      
object v =
bf.Deserialize(stream);
                      
if (predicate(k,
v))
                      
{
                          
count++;
                          
//string d = Encoding.UTF8.GetString(kdp.Data.Buffer, 0,
kdp.Data.Size);
                          
//如何读取Queue类型的主键值

                          
//Console.WriteLine("{0},{1}", p2.State,
p2.Os);
                          
//p2.Os =
"changed";
                          
//stream = new
MemoryStream();
                          
//stream.Position =
0;
                          
//stream.SetLength(0);
                          
//bf.Serialize(stream,
v);
                          
//DbEntry data =
DbEntry.InOut(stream.ToArray());
                          
//cursor.Put(ref
data);
                          
cursor.Delete();
                          
if
(isMatchOnlyOnce)
                          
{
                              
stream.Close();
                              
return
count;
                          
}
                      
}
                  
}stream.Close();
              
}
          
}
           return
count;
      
}

       /**////
<summary>
       ///
用于向支持重复键值的数据库文件添加数据
       ///
</summary>
       /// <param
name="key"></param>
       ///
<param name="value"></param>
      
public void CreateInHashModeWithDup(string key,object
value)
      
{
          
//这里只是更新了一条记录,更新多条同key的情况没有考虑
          
Db db = new
Db(DbCreateFlags.None);
          
db.SetFlags(DbFlags.Dup);
          
DbFile dbf = db.Open(null, this.DBFilePath, null, DbType.Hash,
Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe,
0);
           MemoryStream
stream = new
MemoryStream();
          
BinaryFormatter formatter = new
BinaryFormatter();
          
formatter.Serialize(stream,
value);
           DbEntry
_key =
DbEntry.InOut(Encoding.UTF8.GetBytes(key));
          
DbEntry _data =
DbEntry.InOut(stream.ToArray());
          
if (dbf.Put(null, ref _key, ref _data) !=
0)
              
Console.Write("{0}:输入错误",
key);
          
stream.Close();
          
dbf.Sync();//数据更新

          
db.Close();
      
}
       /**////
<summary>
       ///
默认方式,如果已有键则进行更新操作
       ///
</summary>
       /// <param
name="key"></param>
       ///
<param name="value"></param>
      
public void CreateOrUpdateInHashModeWithoutDup(string key,object
value)
      
{
          
//这里只是更新了一条记录,更新多条同key的情况没有考虑
          
Db db = new
Db(DbCreateFlags.None);
          
//db.SetFlags(DbFlags.Dup);
          
DbFile dbf = db.Open(null, this.DBFilePath, null, DbType.Hash,
Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe,
0);
           MemoryStream
stream = new
MemoryStream();
          
BinaryFormatter formatter = new
BinaryFormatter();
          
formatter.Serialize(stream,
value);
           DbEntry
_key =
DbEntry.InOut(Encoding.UTF8.GetBytes(key));
          
DbEntry _data =
DbEntry.InOut(stream.ToArray());
          
if (dbf.Put(null, ref _key, ref _data) !=
0)
              
Console.Write("{0}:输入错误",
key);
          
stream.Close();
          
dbf.Sync();//数据更新

          
db.Close();
      
}
       public int
UpdateInHashMode(Func<string,object,bool> predicate,object value,bool
isMatchOnlyOnce)
      
{
           int count =
0;
           if (predicate
==
null)
              
return count;
         
//遍历数据
           using (Db
db = new
Db(DbCreateFlags.None))
          
{
              
//这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
              
//Db.OpenFlags.Truncate会清空数据库
              
DbHash dbf = (DbHash)db.Open(null, this.DBFilePath, null,
DbType.Hash,
   Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create,
0);

              
using (DbHashCursor cursor = dbf.OpenCursor(null,
DbFileCursor.CreateFlags.None))
              
{
                  
BinaryFormatter bf = new
BinaryFormatter();
                  
MemoryStream stream = new
MemoryStream();
                 
foreach (KeyDataPair kvp in
cursor)
                  
{
                      
stream.SetLength(0);
                      
stream.Position = 0;

                      
stream.Write(kvp.Data.Buffer, 0,
kvp.Data.Size);
                      
stream.Seek(0,
SeekOrigin.Begin);
                      
string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0,
kvp.Key.Size);
                      
object v =
bf.Deserialize(stream);
                      
if (predicate(k,
v))
                      
{
                          
count++;
                          
stream.SetLength(0);
                          
stream.Position =
0;
                          
bf.Serialize(stream,
value);
                          
DbEntry data =
DbEntry.InOut(stream.ToArray());
                          
cursor.Put(ref data, DbKeyCursor<DbHashCursor,
DbHash>.PutMode.Current);
                          
if
(isMatchOnlyOnce)
                          
{
                              
stream.Close();
                              
return
count;
                          
}
                      
}
                  
}
                  
stream.Close();
              
}
          
}
           return
count;
      
}
       public int
DeleteInHashMode(Func<string,object,bool> predicate,bool
isMatchOnlyOnce)
      
{
           int count =
0;
           if (predicate
==
null)
              
return count;
          
//遍历数据
           using (Db
db = new
Db(DbCreateFlags.None))
          
{
              
//这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
              
//Db.OpenFlags.Truncate会清空数据库
              
DbHash dbf = (DbHash)db.Open(null, this.DBFilePath, null,
DbType.Hash,
   Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create,
0);

              
using (DbHashCursor cursor = dbf.OpenCursor(null,
DbFileCursor.CreateFlags.None))
              
{
                  
BinaryFormatter bf = new
BinaryFormatter();
                  
MemoryStream stream = new
MemoryStream();
                  
foreach (KeyDataPair kvp in
cursor)
                  
{
                      
stream.SetLength(0);
                      
stream.Position =
0;
                      
stream.Write(kvp.Data.Buffer, 0,
kvp.Data.Size);
                      
stream.Seek(0,
SeekOrigin.Begin);
                      
string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0,
kvp.Key.Size);
                      
object v =
bf.Deserialize(stream);
                      
if (predicate(k,
v))
                      
{
                          
count++;
                          
cursor.Delete();
                          
if
(isMatchOnlyOnce)
                          
{
                              
stream.Close();
                              
return
count;
                          
}
                      
}
                  
}
                  
stream.Close();
              
}
          
}
           return
count;
       }
  
}
}

时间: 2024-09-29 03:45:17

.net下BerkeleyDB操作封装C#版(附单元测试)的相关文章

瞎j8封装第二版之数据层的封装

看了以前写的代码,对就是下面这个 手把手封装数据层之DataUtil数据库操作的封装 觉得以前写的代码好烂啊!!!,重新理了一下思路,写得更规范和简练,应该效率也会高很多,用了一下下午写的连接池(半废品...) 瞎j8封装第二版之数据库连接池 下面直接上代码,代码很好理解,就是用了简单的反射,注解的部分我都写了注释 package jdbc; import util.StringUtil; import java.lang.reflect.Field; import java.lang.refl

Linux下查看操作系统信息、内存情况及cpu信息:cpu个数、核心数、线程数

文章转载:http://blog.snsgou.com/post-793.html 1.查看物理CPU的个数 [[email protected] ~]# cat /proc/cpuinfo |grep "physical id"|sort |uniq|wc -l1 2.查看逻辑CPU的个数 [[email protected] ~]# cat /proc/cpuinfo |grep "processor"|wc -l4 3.查看CPU是几核(即,核心数) [[em

关于时间的操作(JavaScript版)——年月日三级联动(默认显示系统时间)

这个功能是大学时自己使用纯JavaScript写的,没有借助Jquery,呵呵呵,看起来有点繁琐,可是在当时依稀的记得功能实现后自己好好的高兴一把了呢,从现在来看那时候的自己是多么的幼稚.多么的无知: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>年月日三级联动(默认显示系统时间)</title> <

关于时间的操作(JavaScript版)——年月日三级级联(默认依次显示请选择年、请选择月和请选择日)

这篇博客和前一篇博客基本相同,只是显示的默认值不同: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>年月日三级级联(默认依次显示请选择年.请选择月和请选择日)</title> <meta http-equiv="content-type" content="text/ht

Linux下RPM操作

在 Linux 操作系统下,几乎所有的软件均通过RPM 进行安装.卸载及管理等操作.RPM 的全称为Redhat Package Manager ,是由Redhat 公司提出的,用于管理Linux 下软件包的软件.Linux 安装时,除了几个核心模块以外,其余几乎所有的模块均通过RPM 完成安装. RPM 有五种操作模式,分别为:安装.卸载.升级.查询和验证. RPM 安装操作 命令: rpm -i 需要安装的包文件名 举例如下: rpm -i example.rpm 安装 example.rp

FEKO 6.0 电磁仿真软件在 Linux下安装以及破解详细步骤(附下载地址和注册程序)

FEKO6.0各版本下载地址(来源于寺院的研究僧): Intel/AMD (32-bit x86) Windows (XP, Vista, Windows 7, Server 2003) feko_distrib_6.0_win32.exe (320 MByte) Linux feko_distrib_6.0_LINUX.tar.gz (392 MByte) Intel/AMD (64-bit x86_64) Windows (XP, Vista, Windows 7, Server 2003,

玩转ASP.NET 5:数据操作封装(一)

1.数据操作封装 1.1概述 在习惯使用ADO.NET数据库访问与操作封装,通常写DataHelper/SQLHelper类.到如今ORM大行其道,我们该爱上存储库模式来封装操作.当然,为了顾及初学者,在封装方法时,还是教学方式,一步步地来,最终重构成通用可重用的代码.所以一开始先不用泛型及写一些扩展方法. 1.2新增目录 1.3代码 面向接口编程方式,先定义接口: using BlogASPNET5.Entity.Accounts; using System.Collections.Gener

Skia简介以及在Windows下编译操作步骤

Skia是一个C++的开源2D向量图形处理函数库(Cairo是一个矢量库),包括字型.坐标转换.位图等等,相当于轻量级的Cairo,目前主要用于Google的Android和Chrome平台,Skia搭配OpenGL/ES与特定的硬件特征,强化显示的效果.另外,Skia是WebKit支持的众多图形平台之一,在WebKit的GraphicsContext.h/.c中有相关实现. Android与Chrome的源代码库中都有一份Skia的复制,因需求不同,做了部分的修改. Skia需要的底层库有:f

寿星天文历Java封装整理版

由于生活和工作的原因,"寿星天文历"我一直没有动,长时间的丢弃后,当重新拾起时,比较费劲.编程就是这样,思维的火花只在当初的那一瞬,一旦熄灭,重新再点燃断掉的思维是很困难的.因为人的"忘记"能力,真的是挺强的,有时回顾或维护以前的代码时,常常会感叹道:这是我写的吗?够牛逼,看不懂!呵呵,这时候注释的作用的凸显出来了,尽管如此有时仅仅靠注释找以前的思路也是很困难. 跑题了,那么,首先对于等着"寿星天文历"封装整理版代码的各位,说声抱歉.这回整理的代