zoukankan      html  css  js  c++  java
  • 目前来说比较.net下最好的bdb操作封装(附单元测试)

      1using System;
      2using System.Collections.Generic;
      3using System.IO;
      4using System.Linq;
      5using System.Runtime.Serialization.Formatters.Binary;
      6using System.Text;
      7using BerkeleyDb;
      8using Component;
      9
     10namespace ToolManager
     11{
     12    public class BDBRecord
     13    {
     14        public object Key getset; }
     15        public string Value getset; }
     16    }
        /// <summary>
     17    /// BDB数据库操作类库
     18    /// </summary>

     19    public class BDBHelper
     20    {
     21
     22        private string DBFilePath getset; }
     23        private DBStoreType DBType getset; }
     24        public enum DBStoreType : byte
     25        {
     26            Auto=1,
     27            Queue,
     28            Hash
     29        }

     30        [Obsolete("该构造函数已废弃 ,请使用BDBHelper(string dbfilePath)")]
     31        public BDBHelper()
     32        {
     33        }

     34
     35        public BDBHelper(string dbfilePath)
     36        {
     37            this.DBFilePath = dbfilePath;
     38        }

     39        [Obsolete("该构造函数已废弃 ,请使用BDBHelper(string dbfilePath)")]
     40        public BDBHelper(string dbfilePath, DBStoreType type)
     41        {
     42            this.DBFilePath = dbfilePath;
     43            this.DBType = type;
     44        }

     45        public BDBRecord FindOne()
     46        {
     47            return this.FindOne(null);
     48        }

     49        public BDBRecord FindOne(Func<objectstringbool> predicate)
     50        {
     51            //Dictionary<string, object> dict = new Dictionary<string, object>();
     52            try
     53            {
     54                Queue格式
     85            }

     86            catch (Exception ex)
     87            {
     88                Hash格式
    121                //}
    122            }

    123            //return dict;
    124            return null;
    125        }

    126        public Dictionary<objectstring> FindAll(Func<objectstringbool> predicate)
    127        {
    128
    129            Dictionary<objectstring> dict = new Dictionary<objectstring>();
    130            try
    131            {
    132                Queue格式
    150            }

    151            catch (Exception ex)
    152            {
    153                Hash格式
    173                //}
    174            }

    175            return dict;
    176        }

    177        public Dictionary<objectstring> FindAll()
    178        {
    179            //either below works fine
    180            //return this.FindAll((s, o) => true);
    181            return this.FindAll(null);
    182        }

    183        private static void _Do(KeyDataPair kvp, Func<objectstringbool> predicate, Dictionary<objectstring> result)
    184        {
    185            BinaryFormatter bf = new BinaryFormatter();
    186            MemoryStream stream = new MemoryStream();
    187            stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    188            stream.Seek(0, SeekOrigin.Begin);
    189            string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0, kvp.Key.Size);
    190            object v = bf.Deserialize(stream);
    191            if (predicate == null)
    192            {
    193                result.Add(v, k);
    194            }

    195            else if (predicate(v, k))
    196            {
    197                result.Add(v, k);
    198            }

    199        }

    200        private static void _Do2(KeyDataPair kvp, Func<objectstringbool> predicate, Dictionary<objectstring> result)
    201        {
    202            BinaryFormatter bf = new BinaryFormatter();
    203            MemoryStream stream = new MemoryStream();
    204            stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    205            stream.Seek(0, SeekOrigin.Begin);
    206            string k = BitConverter.ToInt32(kvp.Key.Buffer, 0).ToString();
    207            object v = bf.Deserialize(stream);
    208            if (predicate == null)
    209            {
    210                result.Add(v, k);
    211            }

    212            else if (predicate(v, k))
    213            {
    214                result.Add(v, k);
    215            }

    216        }

    217        /// <summary>
    218        /// 更新数据库中的数据
    219        /// </summary>
    220        /// <param name="predicate">execute condition</param>
    221        /// <param name="isMatchOnlyOnce">is match only once</param>
    222        /// <returns>effect records</returns>

    223        public int UpdateInQueueMode(Func<intobjectbool> predicate, object value,bool isMatchOnlyOnce)
    224        {
    225                 int count = 0;
    226                 if (predicate == null)
    227                     return 0;
    228               //遍历数据
    229                using (Db db = new Db(DbCreateFlags.None))
    230                {
    231                    db.RecLen = 5000;
    232                    db.RecPad = '.';
    233                    //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    234                    //Db.OpenFlags.Truncate会清空数据库
    235                    DbQueue dbf = (DbQueue)db.Open(nullthis.DBFilePath, null, DbType.Queue,
    236        Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    237
    238                    using (DbQueueCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    239                    {
    240                        BinaryFormatter bf = new BinaryFormatter();
    241                        MemoryStream stream = new MemoryStream();
    242                        foreach (KeyDataPair kdp in cursor)
    243                        {
    244                            int k = BitConverter.ToInt32(kdp.Key.Buffer, 0);
    245                            Console.WriteLine("k={0}", k.ToString());
    246                            stream.SetLength(0);
    247                            stream.Position = 0;
    248                            stream.Write(kdp.Data.Buffer, 0, kdp.Data.Size);
    249                            stream.Seek(0, SeekOrigin.Begin);
    250                            object v = bf.Deserialize(stream);
    251                            if(predicate(k,v))
    252                            {
    253                                count++;
    254                                //string d = Encoding.UTF8.GetString(kdp.Data.Buffer, 0, kdp.Data.Size);
    255                                //如何读取Queue类型的主键值
    256
    257
    258                                //Console.WriteLine("{0},{1}", p2.State, p2.Os);
    259                                //p2.Os = "changed";
    260                                //stream = new MemoryStream();
    261                                stream.Position = 0;
    262                                stream.SetLength(0);
    263                                bf.Serialize(stream, value);
    264                                DbEntry data = DbEntry.InOut(stream.ToArray());
    265                                cursor.Put(ref data);
    266                                if (isMatchOnlyOnce)
    267                                {
    268                                    stream.Close();
    269                                    return count;
    270                                }

    271                            }

    272                        }

    273                            stream.Close();
    274                    }

    275            }

    276            return count;
    277        }

    278
    279        public void CreateInQueueMode(object value)
    280        {
    281            Db PC = new Db(DbCreateFlags.None);
    282            PC.RecLen = 5000;
    283            PC.RecPad = '.';
    284            DbQueue file = (DbQueue)PC.Open(nullthis.DBFilePath, null, DbType.Queue, Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe, 0);
    285            //CreateSecondaryDB(file,"Id.PCs.s",new DbFile.KeyGeneratorFcn(Common.Id));
    286            //CreateSecondaryDB(file, "Id.PCs.s", new DbFile.KeyGeneratorFcn(Common.Id));
    287            //由于数据量不是很大,不考虑使用二级数据库,直接使用游标操作,降低复杂度
    288            //首先遍历数据库看有没有已经存在,如果没有,则添加一个,如果有,改变其状态
    289            BinaryFormatter bf = new BinaryFormatter();
    290            MemoryStream stream= new MemoryStream();
    291            bf.Serialize(stream, value);
    292            DbEntry k = DbEntry.Out(new byte[1024]);
    293            DbEntry data = DbEntry.InOut(stream.ToArray());
    294            file.Append(nullref k, ref data);
    295            stream.Close();
    296            file.Sync();
    297            PC.Close();
    298        }

    299        public int DeleteInQueueMode(Func<intobjectbool> predicate,bool isMatchOnlyOnce)
    300        {
    301            int count = 0;
    302            if (predicate == null)
    303                return 0;
    304            //遍历数据
    305            using (Db db = new Db(DbCreateFlags.None))
    306            {
    307                db.RecLen = 5000;
    308                db.RecPad = '.';
    309                //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    310                //Db.OpenFlags.Truncate会清空数据库
    311                DbQueue dbf = (DbQueue)db.Open(nullthis.DBFilePath, null, DbType.Queue,
    312    Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    313
    314                using (DbQueueCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    315                {
    316                    BinaryFormatter bf = new BinaryFormatter();
    317                    MemoryStream stream = new MemoryStream();
    318                    foreach (KeyDataPair kdp in cursor)
    319                    {
    320                        int k = BitConverter.ToInt32(kdp.Key.Buffer, 0);
    321                        Console.WriteLine("k={0}", k.ToString());
    322                        stream.SetLength(0);
    323                        stream.Position = 0;
    324                        stream.Write(kdp.Data.Buffer, 0, kdp.Data.Size);
    325                        stream.Seek(0, SeekOrigin.Begin);
    326                        object v = bf.Deserialize(stream);
    327                        if (predicate(k, v))
    328                        {
    329                            count++;
    330                            //string d = Encoding.UTF8.GetString(kdp.Data.Buffer, 0, kdp.Data.Size);
    331                            //如何读取Queue类型的主键值
    332
    333
    334                            //Console.WriteLine("{0},{1}", p2.State, p2.Os);
    335                            //p2.Os = "changed";
    336                            //stream = new MemoryStream();
    337                            //stream.Position = 0;
    338                            //stream.SetLength(0);
    339                            //bf.Serialize(stream, v);
    340                            //DbEntry data = DbEntry.InOut(stream.ToArray());
    341                            //cursor.Put(ref data);
    342                            cursor.Delete();
    343                            if (isMatchOnlyOnce)
    344                            {
    345                                stream.Close();
    346                                return count;
    347                            }

    348                        }

    349                    }
    stream.Close();
    350                }

    351            }

    352            return count;
    353        }

    354
    355        /// <summary>
    356        /// 用于向支持重复键值的数据库文件添加数据
    357        /// </summary>
    358        /// <param name="key"></param>
    359        /// <param name="value"></param>

    360        public void CreateInHashModeWithDup(string key,object value)
    361        {
    362            //这里只是更新了一条记录,更新多条同key的情况没有考虑
    363            Db db = new Db(DbCreateFlags.None);
    364            db.SetFlags(DbFlags.Dup);
    365            DbFile dbf = db.Open(nullthis.DBFilePath, null, DbType.Hash, Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe, 0);
    366            MemoryStream stream = new MemoryStream();
    367            BinaryFormatter formatter = new BinaryFormatter();
    368            formatter.Serialize(stream, value);
    369            DbEntry _key = DbEntry.InOut(Encoding.UTF8.GetBytes(key));
    370            DbEntry _data = DbEntry.InOut(stream.ToArray());
    371            if (dbf.Put(nullref _key, ref _data) != 0)
    372                Console.Write("{0}:输入错误", key);
    373            stream.Close();
    374            dbf.Sync();//数据更新 
    375            db.Close();
    376        }

    377        /// <summary>
    378        /// 默认方式,如果已有键则进行更新操作
    379        /// </summary>
    380        /// <param name="key"></param>
    381        /// <param name="value"></param>

    382        public void CreateOrUpdateInHashModeWithoutDup(string key,object value)
    383        {
    384            //这里只是更新了一条记录,更新多条同key的情况没有考虑
    385            Db db = new Db(DbCreateFlags.None);
    386            //db.SetFlags(DbFlags.Dup);
    387            DbFile dbf = db.Open(nullthis.DBFilePath, null, DbType.Hash, Db.OpenFlags.Create|Db.OpenFlags.ThreadSafe, 0);
    388            MemoryStream stream = new MemoryStream();
    389            BinaryFormatter formatter = new BinaryFormatter();
    390            formatter.Serialize(stream, value);
    391            DbEntry _key = DbEntry.InOut(Encoding.UTF8.GetBytes(key));
    392            DbEntry _data = DbEntry.InOut(stream.ToArray());
    393            if (dbf.Put(nullref _key, ref _data) != 0)
    394                Console.Write("{0}:输入错误", key);
    395            stream.Close();
    396            dbf.Sync();//数据更新 
    397            db.Close();
    398        }

    399        public int UpdateInHashMode(Func<string,object,bool> predicate,object value,bool isMatchOnlyOnce)
    400        {
    401            int count = 0;
    402            if (predicate == null)
    403                return count;
    404           //遍历数据
    405            using (Db db = new Db(DbCreateFlags.None))
    406            {
    407                //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    408                //Db.OpenFlags.Truncate会清空数据库
    409                DbHash dbf = (DbHash)db.Open(nullthis.DBFilePath, null, DbType.Hash,
    410    Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    411
    412                using (DbHashCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    413                {
    414                    BinaryFormatter bf = new BinaryFormatter();
    415                    MemoryStream stream = new MemoryStream();
    416                   foreach (KeyDataPair kvp in cursor)
    417                    {
    418                        stream.SetLength(0);
    419                        stream.Position = 0
    420                        stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    421                        stream.Seek(0, SeekOrigin.Begin);
    422                        string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0, kvp.Key.Size);
    423                        object v = bf.Deserialize(stream);
    424                        if (predicate(k, v))
    425                        {
    426                            count++;
    427                            stream.SetLength(0);
    428                            stream.Position = 0;
    429                            bf.Serialize(stream, value);
    430                            DbEntry data = DbEntry.InOut(stream.ToArray());
    431                            cursor.Put(ref data, DbKeyCursor<DbHashCursor, DbHash>.PutMode.Current);
    432                            if (isMatchOnlyOnce)
    433                            {
    434                                stream.Close();
    435                                return count;
    436                            }

    437                        }

    438                    }

    439                    stream.Close();
    440                }

    441            }

    442            return count;
    443        }

    444        public int DeleteInHashMode(Func<string,object,bool> predicate,bool isMatchOnlyOnce)
    445        {
    446            int count = 0;
    447            if (predicate == null)
    448                return count;
    449            //遍历数据
    450            using (Db db = new Db(DbCreateFlags.None))
    451            {
    452                //这里如果应用Db.OpenFlags.Create则在启动后会覆盖同名文件,并新建同名文件
    453                //Db.OpenFlags.Truncate会清空数据库
    454                DbHash dbf = (DbHash)db.Open(nullthis.DBFilePath, null, DbType.Hash,
    455    Db.OpenFlags.ThreadSafe|Db.OpenFlags.Create, 0);
    456
    457                using (DbHashCursor cursor = dbf.OpenCursor(null, DbFileCursor.CreateFlags.None))
    458                {
    459                    BinaryFormatter bf = new BinaryFormatter();
    460                    MemoryStream stream = new MemoryStream();
    461                    foreach (KeyDataPair kvp in cursor)
    462                    {
    463                        stream.SetLength(0);
    464                        stream.Position = 0;
    465                        stream.Write(kvp.Data.Buffer, 0, kvp.Data.Size);
    466                        stream.Seek(0, SeekOrigin.Begin);
    467                        string k = Encoding.UTF8.GetString(kvp.Key.Buffer, 0, kvp.Key.Size);
    468                        object v = bf.Deserialize(stream);
    469                        if (predicate(k, v))
    470                        {
    471                            count++;
    472                            cursor.Delete();
    473                            if (isMatchOnlyOnce)
    474                            {
    475                                stream.Close();
    476                                return count;
    477                            }

    478                        }

    479                    }

    480                    stream.Close();
    481                }

    482            }

    483            return count;
    484        }

    485    }

    486}

    487

    unit test code

      1using System;
      2using System.Collections.Generic;
      3using System.Linq;
      4using System.Text;
      5using Component;
      6using MbUnit.Framework;
      7
      8namespace ToolManager.Test
      9{
     10    [TestFixture]
     11    class BDBHelperTest2
     12    {
     13        hash mode unit test
     69
     70        queue mode unit test
    103
    104    }

    105}

    106
  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/lexus/p/1275164.html
Copyright © 2011-2022 走看看