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()); } }
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 }
public void Expect(JsonTokenType type1, JsonTokenType type2) { if (this.TokenType != type1 && this.TokenType != type2) { throw S3NoSqlException.UnexpectedToken(this.Token); } }
public static void AssertNullOrWhiteSpace(this string _str) { if (string.IsNullOrWhiteSpace(_str)) { throw S3NoSqlException.NullParameter(); } }
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); }
/// <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); }
/// <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); }
/// <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()); }
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(); }
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); }
/// <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); }
/// <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); } } }
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)); } }
/// <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); }
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); }