• .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;
           }
       }
    }

     
  • 相关阅读:
    梦断代码阅读笔记之三
    梦断代码阅读笔记二
    输入法评价
    1的个数
    团队冲刺-10
    第一阶段个人总结03
    第一阶段个人总结02
    第一阶段个人总结01
    学习进度条第十周
    学习进度条第九周
  • 原文地址:https://www.cnblogs.com/MaxIE/p/3748010.html
Copyright © 2020-2023  润新知