From e500d2f7feccad9cf65106c73a52c00367315954 Mon Sep 17 00:00:00 2001 From: adam Date: Tue, 11 Jun 2013 18:28:30 +0700 Subject: [PATCH] #24 --- luaejdb/debian/rules.mk | 6 +- nejdb/Ejdb.SON/BSONArray.cs | 6 ++ nejdb/Ejdb.SON/BSONDocument.cs | 191 +++++++++++++++++++++++++++++++----- nejdb/Ejdb.SON/BSONIterator.cs | 4 +- nejdb/Ejdb.SON/BSONOid.cs | 11 ++- nejdb/Ejdb.SON/BSONValue.cs | 47 ++++++++- nejdb/Ejdb.Tests/TestBSON.cs | 60 ++++++++--- pyejdb/debian/rules.mk | 24 ++++- tcejdb/debian/rules.mk | 34 ++++++- tcejdb/nbproject/configurations.xml | 11 ++- 10 files changed, 347 insertions(+), 47 deletions(-) mode change 120000 => 100755 luaejdb/debian/rules.mk mode change 120000 => 100755 pyejdb/debian/rules.mk mode change 120000 => 100755 tcejdb/debian/rules.mk diff --git a/luaejdb/debian/rules.mk b/luaejdb/debian/rules.mk deleted file mode 120000 index f7358b2..0000000 --- a/luaejdb/debian/rules.mk +++ /dev/null @@ -1 +0,0 @@ -./rules \ No newline at end of file diff --git a/luaejdb/debian/rules.mk b/luaejdb/debian/rules.mk new file mode 100755 index 0000000..ed933e6 --- /dev/null +++ b/luaejdb/debian/rules.mk @@ -0,0 +1,5 @@ +#!/usr/bin/make -f +#export DH_VERBOSE=1 + +%: + dh $@ diff --git a/nejdb/Ejdb.SON/BSONArray.cs b/nejdb/Ejdb.SON/BSONArray.cs index 6d66215..b05db90 100644 --- a/nejdb/Ejdb.SON/BSONArray.cs +++ b/nejdb/Ejdb.SON/BSONArray.cs @@ -25,6 +25,12 @@ namespace Ejdb.SON { } } + public object this[int key] { + get { + return GetObjectValue(key.ToString()); + } + } + public BSONDocument SetNull(int idx) { return base.SetNull(idx.ToString()); } diff --git a/nejdb/Ejdb.SON/BSONDocument.cs b/nejdb/Ejdb.SON/BSONDocument.cs index 2784288..fd4c657 100644 --- a/nejdb/Ejdb.SON/BSONDocument.cs +++ b/nejdb/Ejdb.SON/BSONDocument.cs @@ -27,16 +27,43 @@ namespace Ejdb.SON { /// BSON document deserialized data wrapper. /// [Serializable] - public class BSONDocument : IBSONValue { + public class BSONDocument : IBSONValue, IEnumerable { Dictionary _fields; readonly List _fieldslist; - + int? _cachedhash; + + /// + /// BSON Type this document. + /// + /// + /// Type can be either or + /// + /// The type of the BSON. public virtual BSONType BSONType { get { return BSONType.OBJECT; } } + /// + /// Gets the document keys. + /// + public ICollection Keys { + get { + CheckFields(); + return _fields.Keys; + } + } + + /// + /// Gets count of document keys. + /// + public int KeysCount { + get { + return _fieldslist.Count; + } + } + public BSONDocument() { this._fields = null; this._fieldslist = new List(); @@ -64,6 +91,78 @@ namespace Ejdb.SON { } } + public BSONDocument(BSONDocument doc) : this() { + foreach (var bv in doc) { + Add((BSONValue) bv.Clone()); + } + } + + public IEnumerator GetEnumerator() { + return _fieldslist.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + /// + /// Convert BSON document object into BSON binary data byte array. + /// + /// The byte array. + public byte[] ToByteArray() { + byte[] res; + using (var ms = new MemoryStream()) { + Serialize(ms); + res = ms.ToArray(); + } + return res; + } + + public string ToDebugDataString() { + return BitConverter.ToString(ToByteArray()); + } + + /// + /// Gets the field value. + /// + /// The BSON value. + /// + /// Document field name + public BSONValue GetBSONValue(string key) { + CheckFields(); + BSONValue ov; + if (_fields.TryGetValue(key, out ov)) { + return ov; + } else { + return null; + } + } + + /// + /// Gets the field value object. + /// + /// The object value. + /// + /// Key. + /// Key object or null if the key is not exists or value type is either + /// or + public object GetObjectValue(string key) { + var bv = GetBSONValue(key); + return bv != null ? bv.Value : null; + } + + /// + /// Gets the with the specified key. + /// + /// Key. + /// Key object or null if the key is not exists or value type is either + /// or + public object this[string key] { + get { + return GetObjectValue(key); + } + } + public BSONDocument SetNull(string key) { return SetBSONValue(new BSONValue(BSONType.NULL, key)); } @@ -149,15 +248,28 @@ namespace Ejdb.SON { } public BSONValue DropValue(string key) { - var bv = this[key]; + var bv = GetBSONValue(key); if (bv == null) { return bv; } + _cachedhash = null; _fields.Remove(key); _fieldslist.RemoveAll(x => x.Key == key); return bv; } + /// + /// Removes all data from document. + /// + public void Clear() { + _cachedhash = null; + _fieldslist.Clear(); + if (_fields != null) { + _fields.Clear(); + _fields = null; + } + } + public void Serialize(Stream os) { if (os.CanSeek) { long start = os.Position; @@ -189,16 +301,57 @@ namespace Ejdb.SON { } os.Flush(); } - //.////////////////////////////////////////////////////////////////// - // Private staff - //.////////////////////////////////////////////////////////////////// - internal BSONValue this[string key] { - get { - return GetBSONValue(key); + + public override bool Equals(object obj) { + if (obj == null) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } + if (!(obj is BSONDocument)) { + return false; + } + BSONDocument d1 = this; + BSONDocument d2 = ((BSONDocument) obj); + if (d1.KeysCount != d2.KeysCount) { + return false; + } + foreach (BSONValue bv1 in d1._fieldslist) { + BSONValue bv2 = d2.GetBSONValue(bv1.Key); + if (bv1 != bv2) { + return false; + } + } + return true; + } + + public override int GetHashCode() { + if (_cachedhash != null) { + return (int) _cachedhash; + } + unchecked { + int hash = 1; + foreach (var bv in _fieldslist) { + hash = (hash * 31) + bv.GetHashCode(); + } + _cachedhash = hash; } + return (int) _cachedhash; + } + + public static bool operator ==(BSONDocument d1, BSONDocument d2) { + return Equals(d1, d2); } + public static bool operator !=(BSONDocument d1, BSONDocument d2) { + return !(d1 == d2); + } + //.////////////////////////////////////////////////////////////////// + // Private staff + //.////////////////////////////////////////////////////////////////// internal BSONDocument Add(BSONValue bv) { + _cachedhash = null; _fieldslist.Add(bv); if (_fields != null) { _fields[bv.Key] = bv; @@ -206,31 +359,21 @@ namespace Ejdb.SON { return this; } - internal BSONValue GetBSONValue(string key) { - CheckFields(); - return _fields[key]; - } - internal BSONDocument SetBSONValue(BSONValue val) { + _cachedhash = null; CheckFields(); - var ov = _fields[val.Key]; - if (ov != null) { + BSONValue ov; + if (_fields.TryGetValue(val.Key, out ov)) { ov.Key = val.Key; ov.BSONType = val.BSONType; ov.Value = val.Value; } else { _fieldslist.Add(val); - _fields[val.Key] = val; + _fields.Add(val.Key, val); } return this; } - internal object GetObjectValue(string key) { - CheckFields(); - var bv = _fields[key]; - return bv != null ? bv.Value : null; - } - protected virtual void CheckKey(string key) { } @@ -340,7 +483,7 @@ namespace Ejdb.SON { protected void WriteTypeAndKey(BSONValue bv, ExtBinaryWriter bw) { bw.Write((byte) bv.BSONType); - bw.WriteBSONString(bv.Key); + bw.WriteCString(bv.Key); } protected void CheckFields() { diff --git a/nejdb/Ejdb.SON/BSONIterator.cs b/nejdb/Ejdb.SON/BSONIterator.cs index a3373d8..6821baf 100644 --- a/nejdb/Ejdb.SON/BSONIterator.cs +++ b/nejdb/Ejdb.SON/BSONIterator.cs @@ -55,7 +55,7 @@ namespace Ejdb.SON { throw new IOException("Input stream must be seekable"); } this._input = new ExtBinaryReader(input); - this._ctype = BSONType.EOO; + this._ctype = BSONType.UNKNOWN; this._doclen = _input.ReadInt32(); if (this._doclen < 5) { Dispose(); @@ -94,7 +94,7 @@ namespace Ejdb.SON { if (_ctype == BSONType.EOO) { return BSONType.EOO; } - if (_ctype != BSONType.UNKNOWN) { + if (!_entryDataSkipped && _ctype != BSONType.UNKNOWN) { SkipData(); } byte bv = _input.ReadByte(); diff --git a/nejdb/Ejdb.SON/BSONOid.cs b/nejdb/Ejdb.SON/BSONOid.cs index 192d3da..9059792 100644 --- a/nejdb/Ejdb.SON/BSONOid.cs +++ b/nejdb/Ejdb.SON/BSONOid.cs @@ -91,6 +91,12 @@ namespace Ejdb.SON { } public override bool Equals(object obj) { + if (obj == null) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } if (obj is BSONOid) { return (CompareTo((BSONOid) obj) == 0); } @@ -102,10 +108,9 @@ namespace Ejdb.SON { } public static bool operator ==(BSONOid a, BSONOid b) { - if (ReferenceEquals(a, b)) { + if (ReferenceEquals(a, b)) return true; - } - if (a == null || b == null) { + if ((object) a == null || (object) b == null) { return false; } return a.Equals(b); diff --git a/nejdb/Ejdb.SON/BSONValue.cs b/nejdb/Ejdb.SON/BSONValue.cs index f73c62a..9f3c77f 100644 --- a/nejdb/Ejdb.SON/BSONValue.cs +++ b/nejdb/Ejdb.SON/BSONValue.cs @@ -21,7 +21,7 @@ namespace Ejdb.SON { /// BSON field value. /// [Serializable] - public sealed class BSONValue : IBSONValue { + public sealed class BSONValue : IBSONValue, ICloneable { /// /// BSON.Type @@ -47,9 +47,54 @@ namespace Ejdb.SON { public BSONValue(BSONType type, string key) : this(type, key, null) { } + public override bool Equals(object obj) { + if (obj == null) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } + if (obj.GetType() != typeof(BSONValue)) { + return false; + } + BSONValue other = (BSONValue) obj; + if (BSONType != other.BSONType || Key != other.Key) { + return false; + } + if (Value != null) { + return Value.Equals(other.Value); + } else { + return (Value == other.Value); + } + } + + public static bool operator ==(BSONValue v1, BSONValue v2) { + if (ReferenceEquals(v1, v2)) { + return true; + } + if ((object) v1 == null || (object) v2 == null) { + return false; + } + return v1.Equals(v2); + } + + public static bool operator !=(BSONValue v1, BSONValue v2) { + return !(v1 == v2); + } + + public override int GetHashCode() { + unchecked { + return BSONType.GetHashCode() ^ (Value != null ? Value.GetHashCode() : 0); + } + } + public override string ToString() { return string.Format("[BSONValue: BSONType={0}, Key={1}, Value={2}]", BSONType, Key, Value); } + + public object Clone() { + return new BSONValue(this.BSONType, this.Key, this.Value); + } } } diff --git a/nejdb/Ejdb.Tests/TestBSON.cs b/nejdb/Ejdb.Tests/TestBSON.cs index 1cb9422..f9ac5a8 100644 --- a/nejdb/Ejdb.Tests/TestBSON.cs +++ b/nejdb/Ejdb.Tests/TestBSON.cs @@ -25,24 +25,60 @@ namespace Ejdb.Tests { [Test] public void TestSerializeEmpty() { - MemoryStream ms = new MemoryStream(); BSONDocument doc = new BSONDocument(); - doc.Serialize(ms); - string hv = TestUtils.ToHexString(ms.ToArray()); - ms.Close(); - Assert.AreEqual("05-00-00-00-00", hv); + Assert.AreEqual("05-00-00-00-00", doc.ToDebugDataString()); } [Test] - public void TestSerializeSimple() { - MemoryStream ms = new MemoryStream(); + public void TestSerialize1() { + byte[] bdata; BSONDocument doc = new BSONDocument(); - doc.Serialize(ms); - string hv = TestUtils.ToHexString(ms.ToArray()); - ms.Close(); - Console.WriteLine("HV=" + hv); - } + doc.SetNumber("0", 1); + //0C-00-00-00 len + //10 type + //30-00 key + //01-00-00-00 int val + //00 zero term + bdata = doc.ToByteArray(); + Assert.AreEqual("0C-00-00-00-10-30-00-01-00-00-00-00", doc.ToDebugDataString()); + Assert.AreEqual(bdata.Length, (int) Convert.ToByte(doc.ToDebugDataString().Substring(0, 2), 16)); + + BSONDocument doc2 = new BSONDocument(doc.ToByteArray()); + Assert.AreEqual(1, doc2.KeysCount); + int c = 0; + foreach (BSONValue bv in doc2) { + c++; + Assert.IsNotNull(bv); + Assert.AreEqual(BSONType.INT, bv.BSONType); + Assert.AreEqual("0", bv.Key); + Assert.AreEqual(1, bv.Value); + } + Assert.That(c > 0); + doc2.SetNumber("0", 2); + Assert.AreEqual(1, doc2.KeysCount); + object ival = doc2["0"]; + Assert.IsInstanceOfType(typeof(int), ival); + Assert.AreEqual(2, ival); + + doc2.SetNumber("1", Int32.MaxValue); + //13-00-00-00 + //10 + //30-00 + //02-00-00-00 + //10-31-00 + //FF-FF-FF-7F + //00 + Assert.AreEqual("13-00-00-00-10-30-00-02-00-00-00-10-31-00-FF-FF-FF-7F-00", + doc2.ToDebugDataString()); + doc2 = new BSONDocument(doc2); + Assert.AreEqual("13-00-00-00-10-30-00-02-00-00-00-10-31-00-FF-FF-FF-7F-00", + doc2.ToDebugDataString()); + + doc2 = new BSONDocument(doc2.ToByteArray()); + Assert.AreEqual("13-00-00-00-10-30-00-02-00-00-00-10-31-00-FF-FF-FF-7F-00", + doc2.ToDebugDataString()); + } } } diff --git a/pyejdb/debian/rules.mk b/pyejdb/debian/rules.mk deleted file mode 120000 index f7358b2..0000000 --- a/pyejdb/debian/rules.mk +++ /dev/null @@ -1 +0,0 @@ -./rules \ No newline at end of file diff --git a/pyejdb/debian/rules.mk b/pyejdb/debian/rules.mk new file mode 100755 index 0000000..55f514f --- /dev/null +++ b/pyejdb/debian/rules.mk @@ -0,0 +1,23 @@ +#!/usr/bin/make -f + +PYTHON3=$(shell py3versions -vr) + +%: + dh $@ --with python3 + +build-python%: + python$* setup.py build + +override_dh_auto_build: $(PYTHON3:%=build-python%) + dh_auto_build + +install-python%: + python$* setup.py install --root=$(CURDIR)/debian/tmp --install-layout=deb + +override_dh_auto_install: $(PYTHON3:%=install-python%) + dh_auto_install + +override_dh_auto_clean: + dh_auto_clean + rm -rf build + rm -rf *.egg-info diff --git a/tcejdb/debian/rules.mk b/tcejdb/debian/rules.mk deleted file mode 120000 index f7358b2..0000000 --- a/tcejdb/debian/rules.mk +++ /dev/null @@ -1 +0,0 @@ -./rules \ No newline at end of file diff --git a/tcejdb/debian/rules.mk b/tcejdb/debian/rules.mk new file mode 100755 index 0000000..da134f2 --- /dev/null +++ b/tcejdb/debian/rules.mk @@ -0,0 +1,33 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS = -g -Wall -Wextra $(if $(findstring noopt,$(DEB_BUILD_OPTIONS)),-O0,-O2) +LDFLAGS= -Wl,-z,defs + +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +%: + dh $@ + +override_dh_auto_test: + $(MAKE) check-ejdb + +override_dh_auto_configure: + dh_auto_configure -- \ + $(if $(findstring $(DEB_BUILD_ARCH),s390 s390x),--disable-pthread) \ + --enable-devel \ + --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ + CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" + +clean: + dh $@ + ! test -e Makefile || $(MAKE) distclean + rm -f build-*-stamp + +override_dh_strip: + dh_strip --dbg-package=libtcejdb9-dbg + +.PHONY: override_dh_strip override_dh_auto_test override_dh_auto_configure clean diff --git a/tcejdb/nbproject/configurations.xml b/tcejdb/nbproject/configurations.xml index 3ea2b0f..30dedfb 100644 --- a/tcejdb/nbproject/configurations.xml +++ b/tcejdb/nbproject/configurations.xml @@ -49,6 +49,7 @@ tcftest.c tchdb.c tchdb.h + tchdb2.h tchmgr.c tchmttest.c tchtest.c @@ -95,7 +96,7 @@ . ${MAKE} -f Makefile ${MAKE} -f Makefile clean - testejdb/t4 + ./tchmttest _GNU_SOURCE=1 @@ -373,10 +374,14 @@ - ../../../../include . /usr/local/include + + EJDB_STATIC + _DEBUG + _TC_APPLIBS="-L/usr/local/lib -lpthread -lz -lrt -lm -lc " + @@ -837,6 +842,8 @@ + + -- 2.7.4