Example #1
0
        protected override void ReadContent(ByteReader reader)
        {
            var info = reader.ReadString(HEADER_INFO.Length);
            var ver  = reader.ReadByte();

            if (info != HEADER_INFO)
            {
                throw S3NoSqlException.InvalidDatabase();
            }
            if (ver != FILE_VERSION)
            {
                throw S3NoSqlException.InvalidDatabaseVersion(ver);
            }

            reader.ReadUInt16(); // to be compatible with old "ChangeID"

            this.FreeEmptyPageID = reader.ReadUInt32();
            this.LastPageID      = reader.ReadUInt32();
            this.UserVersion     = reader.ReadUInt16();
            this.Password        = reader.ReadBytes(this.Password.Length);
            this.Salt            = reader.ReadBytes(this.Salt.Length);

            // read page collections references (position on end of page)
            var cols = reader.ReadByte();

            for (var i = 0; i < cols; i++)
            {
                this.CollectionPages.Add(reader.ReadString(), reader.ReadUInt32());
            }
        }
Example #2
0
        private void InsertDocument(string _collectionName, BsonDocument doc)
        {
            BsonValue id;

            // if no _id, add one as ObjectId
            if (!doc.RawValue.TryGetValue("_id", out id))
            {
                doc["_id"] = id = ObjectId.NewObjectId();
            }

            // test if _id is a valid type
            if (id.IsNull || id.IsMinValue || id.IsMaxValue)
            {
                throw S3NoSqlException.InvalidDataType("_id", id);
            }

            //m_Log.Write(Logger.COMMAND, "insert document on '{0}' :: _id = {1}", col.CollectionName, id);

            // serialize object
            var bytes = BsonSerializer.Serialize(doc);

            using (MemoryStream stream = new MemoryStream(bytes))
            {
                S3Helper.WriteDocument(m_S3Client, DataBucket, Database, _collectionName, id.AsString, "application/ubjson", stream);
            }

            //TODO Queue calculation of the indexes for this document
        }
Example #3
0
 public void Expect(JsonTokenType type1, JsonTokenType type2)
 {
     if (this.TokenType != type1 && this.TokenType != type2)
     {
         throw S3NoSqlException.UnexpectedToken(this.Token);
     }
 }
Example #4
0
 public static void AssertNullOrWhiteSpace(this string _str)
 {
     if (string.IsNullOrWhiteSpace(_str))
     {
         throw S3NoSqlException.NullParameter();
     }
 }
Example #5
0
        internal BsonValue ReadValue(JsonToken token)
        {
            switch (token.TokenType)
            {
            case JsonTokenType.String: return(token.Token);

            case JsonTokenType.BeginDoc: return(this.ReadObject());

            case JsonTokenType.BeginArray: return(this.ReadArray());

            case JsonTokenType.Number:
                return(token.Token.Contains(".") ?
                       new BsonValue(Convert.ToDouble(token.Token, CultureInfo.InvariantCulture.NumberFormat)) :
                       new BsonValue(Convert.ToInt32(token.Token)));

            case JsonTokenType.Word:
                switch (token.Token)
                {
                case "null": return(BsonValue.Null);

                case "true": return(true);

                case "false": return(false);

                default: throw S3NoSqlException.UnexpectedToken(token.Token);
                }
            }

            throw S3NoSqlException.UnexpectedToken(token.Token);
        }
Example #6
0
        /// <summary>
        /// Returns first free index slot to be used
        /// </summary>
        public CollectionIndex GetFreeIndex()
        {
            for (byte i = 0; i < this.Indexes.Length; i++)
            {
                if (this.Indexes[i].IsEmpty)
                {
                    return(this.Indexes[i]);
                }
            }

            throw S3NoSqlException.IndexLimitExceeded(this.CollectionName);
        }
Example #7
0
        /// <summary>
        /// Copy all file content to a steam
        /// </summary>
        public void Download(string id, Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            var file = this.FindById(id);

            if (file == null)
            {
                throw S3NoSqlException.FileNotFound(id);
            }

            file.CopyDataTo(stream);
        }
Example #8
0
        /// <summary>
        /// Load data inside storage and returns as Stream
        /// </summary>
        public Stream OpenRead(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException("id");
            }

            var file = this.FindById(id);

            if (file == null)
            {
                throw S3NoSqlException.FileNotFound(id);
            }

            return(file.OpenReadData());
        }
Example #9
0
        internal S3NoSqlFileInfo(S3NoSqlEngine engine, string id, string filename)
        {
            if (!IdPattern.IsMatch(id))
            {
                throw S3NoSqlException.InvalidFormat("FileId", id);
            }

            m_Engine = engine;

            this.Id         = id;
            this.Filename   = Path.GetFileName(filename);
            this.MimeType   = MimeTypeConverter.GetMimeType(this.Filename);
            this.Length     = 0;
            this.Chunks     = 0;
            this.UploadDate = DateTime.Now;
            this.Metadata   = new BsonDocument();
        }
Example #10
0
        public static PropertyInfo SelectProperty(IEnumerable <PropertyInfo> props, params Func <PropertyInfo, bool>[] predicates)
        {
            foreach (var predicate in predicates)
            {
                var prop = props.FirstOrDefault(predicate);

                if (prop != null)
                {
                    if (!prop.CanRead || !prop.CanWrite)
                    {
                        throw S3NoSqlException.PropertyReadWrite(prop);
                    }

                    return(prop);
                }
            }

            return(null);
        }
Example #11
0
        /// <summary>
        /// Read a page with correct instance page object. Checks for pageType
        /// </summary>
        public static BasePage ReadPage(byte[] buffer)
        {
            var reader = new ByteReader(buffer);

            var pageID   = reader.ReadUInt32();
            var pageType = (PageType)reader.ReadByte();

            if (pageID == 0 && (byte)pageType > 5)
            {
                throw S3NoSqlException.InvalidDatabase();
            }

            var page = CreateInstance(pageID, pageType);

            page.ReadHeader(reader);
            page.ReadContent(reader);

            page.DiskData = buffer;

            return(page);
        }
Example #12
0
        /// <summary>
        /// Create a new instance from a Type
        /// </summary>
        public static object CreateInstance(Type type)
        {
            try
            {
                CreateObject c;
                if (_cacheCtor.TryGetValue(type, out c))
                {
                    return(c());
                }
            }
            catch (Exception ex)
            {
                throw S3NoSqlException.InvalidCtor(type, ex);
            }

            lock (_cacheCtor)
            {
                try
                {
                    CreateObject c = null;

                    if (type.GetTypeInfo().IsClass)
                    {
                        _cacheCtor.Add(type, c = CreateClass(type));
                    }
                    else if (type.GetTypeInfo().IsInterface) // some know interfaces
                    {
                        if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(IList <>))
                        {
                            return(CreateInstance(GetGenericListOfType(UnderlyingTypeOf(type))));
                        }
                        else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(ICollection <>))
                        {
                            return(CreateInstance(GetGenericListOfType(UnderlyingTypeOf(type))));
                        }
                        else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(IEnumerable <>))
                        {
                            return(CreateInstance(GetGenericListOfType(UnderlyingTypeOf(type))));
                        }
                        else if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(IDictionary <,>))
                        {
                            var k = type.GetTypeInfo().GenericTypeArguments[0];
                            var v = type.GetTypeInfo().GenericTypeArguments[1];
                            return(CreateInstance(GetGenericDictionaryOfType(k, v)));
                        }
                        else
                        {
                            throw S3NoSqlException.InvalidCtor(type, null);
                        }
                    }
                    else // structs
                    {
                        _cacheCtor.Add(type, c = CreateStruct(type));
                    }

                    return(c());
                }
                catch (Exception ex)
                {
                    throw S3NoSqlException.InvalidCtor(type, ex);
                }
            }
        }
Example #13
0
        internal BsonValue Serialize(Type type, object obj, int depth)
        {
            if (++depth > MAX_DEPTH)
            {
                throw S3NoSqlException.DocumentMaxDepth(MAX_DEPTH, type);
            }

            if (obj == null)
            {
                return(BsonValue.Null);
            }

            Func <object, BsonValue> custom;

            // if is already a bson value
            if (obj is BsonValue)
            {
                return(new BsonValue((BsonValue)obj));
            }

            // test string - mapper has some special options
            else if (obj is String)
            {
                var str = this.TrimWhitespace ? (obj as String).Trim() : (String)obj;

                if (this.EmptyStringToNull && str.Length == 0)
                {
                    return(BsonValue.Null);
                }
                else
                {
                    return(new BsonValue(str));
                }
            }
            // basic Bson data types (cast datatype for better performance optimization)
            else if (obj is Int32)
            {
                return(new BsonValue((Int32)obj));
            }
            else if (obj is Int64)
            {
                return(new BsonValue((Int64)obj));
            }
            else if (obj is Double)
            {
                return(new BsonValue((Double)obj));
            }
            else if (obj is Byte[])
            {
                return(new BsonValue((Byte[])obj));
            }
            else if (obj is ObjectId)
            {
                return(new BsonValue((ObjectId)obj));
            }
            else if (obj is Guid)
            {
                return(new BsonValue((Guid)obj));
            }
            else if (obj is Boolean)
            {
                return(new BsonValue((Boolean)obj));
            }
            else if (obj is DateTime)
            {
                return(new BsonValue((DateTime)obj));
            }
            // basic .net type to convert to bson
            else if (obj is Int16 || obj is UInt16 || obj is Byte || obj is SByte)
            {
                return(new BsonValue(Convert.ToInt32(obj)));
            }
            else if (obj is UInt32 || obj is UInt64)
            {
                return(new BsonValue(Convert.ToInt64(obj)));
            }
            else if (obj is Single || obj is Decimal)
            {
                return(new BsonValue(Convert.ToDouble(obj)));
            }
            else if (obj is Char || obj is Enum)
            {
                return(new BsonValue(obj.ToString()));
            }
            // check if is a custom type
            else if (_customSerializer.TryGetValue(type, out custom) || _customSerializer.TryGetValue(obj.GetType(), out custom))
            {
                return(custom(obj));
            }
            // for dictionary
            else if (obj is IDictionary)
            {
                var itemType = type.GetTypeInfo().GenericTypeArguments[1];

                return(this.SerializeDictionary(itemType, obj as IDictionary, depth));
            }
            // check if is a list or array
            else if (obj is IEnumerable)
            {
                return(this.SerializeArray(Reflection.GetListItemType(obj.GetType()), obj as IEnumerable, depth));
            }
            // otherwise serialize as a plain object
            else
            {
                return(this.SerializeObject(type, obj, depth));
            }
        }
Example #14
0
        /// <summary>
        /// Use this method to override how your class can be, by defalut, mapped from entity to Bson document.
        /// Returns an EntityMapper from each requested Type
        /// </summary>
        protected virtual EntityMapper BuildEntityMapper(Type type)
        {
            var mapper = new EntityMapper
            {
                Members = new List <MemberMapper>(),
                ForType = type
            };

            var idAttr     = typeof(BsonIdAttribute);
            var ignoreAttr = typeof(BsonIgnoreAttribute);
            var fieldAttr  = typeof(BsonFieldAttribute);
            var indexAttr  = typeof(BsonIndexAttribute);
            var dbrefAttr  = typeof(BsonRefAttribute);

            foreach (var memberInfo in this.GetTypeMembers(type))
            {
                // checks [BsonIgnore]
                if (memberInfo.IsDefined(ignoreAttr, true))
                {
                    continue;
                }

                // checks field name conversion
                var name = this.ResolveFieldName(memberInfo.Name);

                // checks if is _id
                if (this.IsMemberId(type, memberInfo))
                {
                    name = "_id";
                }

                // check if property has [BsonField]
                var field = (BsonFieldAttribute)memberInfo.GetCustomAttributes(fieldAttr, false).FirstOrDefault();

                // check if property has [BsonField] with a custom field name
                if (field != null && field.Name != null)
                {
                    name = field.Name;
                }

                // test if field name is OK (avoid to check in all instances) - do not test internal classes, like DbRef
                if (BsonDocument.IsValidFieldName(name) == false)
                {
                    throw S3NoSqlException.InvalidFormat(memberInfo.Name, name);
                }

                // create getter/setter function
                var getter = Reflection.CreateGenericGetter(type, memberInfo);
                var setter = Reflection.CreateGenericSetter(type, memberInfo);

                // check if property has [BsonId] to get with was setted AutoId = true
                var autoId = (BsonIdAttribute)memberInfo.GetCustomAttributes(idAttr, false).FirstOrDefault();

                // checks if this proerty has [BsonIndex]
                var index = (BsonIndexAttribute)memberInfo.GetCustomAttributes(indexAttr, false).FirstOrDefault();

                // get data type
                var dataType = memberInfo is PropertyInfo ?
                               (memberInfo as PropertyInfo).PropertyType :
                               (memberInfo as FieldInfo).FieldType;

                // check if datatype is list/array
                var isList = Reflection.IsList(dataType);

                // create a property mapper
                var member = new MemberMapper
                {
                    AutoId         = autoId == null ? true : autoId.AutoId,
                    FieldName      = name,
                    MemberName     = memberInfo.Name,
                    DataType       = dataType,
                    IsUnique       = index == null ? false : index.Unique,
                    IsList         = isList,
                    UnderlyingType = isList ? Reflection.GetListItemType(dataType) : dataType,
                    Getter         = getter,
                    Setter         = setter
                };

                // check if property has [BsonRef]
                var dbRef = (BsonRefAttribute)memberInfo.GetCustomAttributes(dbrefAttr, false).FirstOrDefault();

                if (dbRef != null && memberInfo is PropertyInfo)
                {
                    BsonMapper.RegisterDbRef(this, member, dbRef.Collection);
                }

                // support callback to user modify member mapper
                if (this.ResolveMember != null)
                {
                    this.ResolveMember(type, memberInfo, member);
                }

                // test if has name and there is no duplicate field
                if (member.FieldName != null && mapper.Members.Any(x => x.FieldName == name) == false)
                {
                    mapper.Members.Add(member);
                }
            }

            return(mapper);
        }
Example #15
0
        internal object Deserialize(Type type, BsonValue value)
        {
            Func <BsonValue, object> custom;

            // null value - null returns
            if (value.IsNull)
            {
                return(null);
            }

            // if is nullable, get underlying type
            else if (Reflection.IsNullable(type))
            {
                type = Reflection.UnderlyingTypeOf(type);
            }

            // check if your type is already a BsonValue/BsonDocument/BsonArray
            if (type == typeof(BsonValue))
            {
                return(new BsonValue(value));
            }
            else if (type == typeof(BsonDocument))
            {
                return(value.AsDocument);
            }
            else if (type == typeof(BsonArray))
            {
                return(value.AsArray);
            }

            // raw values to native bson values
            else if (_bsonTypes.Contains(type))
            {
                return(value.RawValue);
            }

            // simple ConvertTo to basic .NET types
            else if (_basicTypes.Contains(type))
            {
                return(Convert.ChangeType(value.RawValue, type));
            }

            // enum value is an int
            else if (type.GetTypeInfo().IsEnum)
            {
                return(Enum.Parse(type, value.AsString));
            }

            // test if has a custom type implementation
            else if (_customDeserializer.TryGetValue(type, out custom))
            {
                return(custom(value));
            }

            // if value is array, deserialize as array
            else if (value.IsArray)
            {
                if (type.IsArray)
                {
                    return(this.DeserializeArray(type.GetElementType(), value.AsArray));
                }
                else
                {
                    return(this.DeserializeList(type, value.AsArray));
                }
            }

            // if value is document, deserialize as document
            else if (value.IsDocument)
            {
                BsonValue typeField;
                var       doc = value.AsDocument;

                // test if value is object and has _type
                if (doc.RawValue.TryGetValue("_type", out typeField))
                {
                    type = Type.GetType(typeField.AsString);

                    if (type == null)
                    {
                        throw S3NoSqlException.InvalidTypedName(typeField.AsString);
                    }
                }

                var o = _typeInstanciator(type);

                if (o is IDictionary && type.GetTypeInfo().IsGenericType)
                {
                    var k = type.GetTypeInfo().GenericTypeArguments[0];
                    var t = type.GetTypeInfo().GenericTypeArguments[1];

                    this.DeserializeDictionary(k, t, (IDictionary)o, value.AsDocument);
                }
                else
                {
                    this.DeserializeObject(type, o, doc);
                }

                return(o);
            }

            // in last case, return value as-is - can cause "cast error"
            // it's used for "public object MyInt { get; set; }"
            return(value.RawValue);
        }