.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;
}
}
}
.net下BerkeleyDB操作封装C#版(附单元测试)的更多相关文章
- 瞎j8封装第二版之数据层的封装
看了以前写的代码,对就是下面这个 手把手封装数据层之DataUtil数据库操作的封装 觉得以前写的代码好烂啊!!!,重新理了一下思路,写得更规范和简练,应该效率也会高很多,用了一下下午写的连接池(半废 ...
- DOM操作(基础版)
DOM操作(基础版) DOM是document Object Model的缩写,简称文档对象模型.只要记住这是操作文档的就行了. DOM基础选择器 1.getElementById(id); //获取 ...
- RPM方式安装MySQL5.6和windows下安装mysql解压版
下载地址: http://cdn.MySQL.com/archives/mysql-5.6/MySQL-server-5.6.13-1.el6.x86_64.rpmhttp://cdn.mysql.c ...
- Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类
本文目录 1. 前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...
- js操作文件 HTML5版
js操作文件 HTML5版,有需要的朋友可以参考下. <!DOCTYPE html> <html> <head> <title>JSFileReader ...
- Windows下对文件夹下所有图片批量重命名(附C++,python,matlab代码)
https://blog.csdn.net/u011574296/article/details/72956446: Windows下对文件夹下所有图片批量重命名(附C++,python,matlab ...
- Python编程:从入门到项目实践高清版附PDF百度网盘免费下载|Python入门编程免费领取
百度网盘:Python编程:从入门到项目实践高清版附PDF免费下载 提取码:oh2g 第一部分 基础知识第1章 起步 21.1 搭建编程环境 21.1.1 Python 2和Python 3 21 ...
- windows 下使用免安裝版MySql5.5
windows 下使用面安裝版MySql5.5步驟如下 1.解壓下載的壓縮文件到指定文件夾.如:F:\DB\mysql-5.5.18-win32\mysql-5.5.18-win32: 2.在根目錄F ...
- Ubuntu 11.10下GRUB 2 1.99版编译安装笔记
Ubuntu 11.10下GRUB 2 1.99版编译安装笔记 以下的安装笔记,都是QLi自己学习grub2 时,所整理的,还是新手,有错误的话,请大家帮忙就别提出来了. 最新版grub V1.99官 ...
随机推荐
- oracle备忘
一.explain plan a)explain plan for select ... select * from table(dbms_xplan.display()); function dis ...
- $watch监听数据变化和run方法
angular中$watch方法可以监听数据的变化. $scope.$watch('phone',function(){ $scope.phone.fre = $scope.phone.num> ...
- 阿牛OCX编程助手
※◆☆★☆◆※欢迎使用阿牛OCX编程助手,此程序为按键精灵专用,如终请联系作者QQ:82850696*0*测试版已停用*0*2014-12-27 14:05:59*哈密*E2873D0137C6D04 ...
- NSString 的 compare 方法
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange ...
- web form 复合控件
DropDownList 下拉列表 会被编译为select option ps.name 服务端常用,id 客户端常用 一般用法: 一.将数据放进去 方法一:同WinForm相同,给定数据源,然后绑定 ...
- 1606: [Usaco2008 Dec]Hay For Sale 购买干草
Description 约翰遭受了重大的损失:蟑螂吃掉了他所有的干草,留下一群饥饿的牛.他乘着容量为C(1≤C≤50000)个单位的马车,去顿因家买一些干草. 顿因有H(1≤H≤5000)包 ...
- 手写DataSet,DataTable
一:DataSet DataSet ds = new DataSet();//创建DataSet DataTable dt = new DataTable();//创建一个DataTalbe dt.C ...
- 文件过滤器 filter
OpenFileDialog对话框的Filter属性说明: 首先说明一个示例,分析一下Filter属性的构成:“ Excel文件|*.xls ”,前面的“Excel文件”成为标签,是一个可读的字符串, ...
- Coins(HDU 2844):一个会超时的多重背包
Coins HDU 2844 不能用最基础的多重背包模板:会超时的!!! 之后看了二进制优化了的多重背包. 就是把多重转变成01背包: 具体思路见:http://www.cnblogs.com/tt ...
- OFM管理
OMF:oracle management files 作用:不用指定文件的路径大小名字 OMF管理数据文件:db_create_file_dest 传统方式:SQL>create tables ...