private static IEnumerable <string> createMembers(Type table, Dictionary <Type, int> typeIndex) { foreach (var property in table.GetProperties()) { var attrs = property.GetCustomAttributes(true); if (attrs.Any(a => a is Column)) { string orderBy = (attrs.Single(a => a is Column) as Column).OrderBy ? " orderby" : ""; string type; if (property.PropertyType.IsGenericType) { type = property.PropertyType.Name + "<" + String.Join("+", property.PropertyType.GetGenericArguments().Select(x => x.Name)) + ">"; } else { type = property.PropertyType.Name; } yield return(type + " " + property.Name + orderBy); } else if (attrs.Any(a => a is ForeignKey && !(a as ForeignKey).Hidden)) { yield return("ref" + typeIndex[property.PropertyType] + " " + property.Name); } else if (MultiReference.IsReal(property)) { yield return("sub=" + typeIndex[property.PropertyType.GetGenericArguments()[0]]); } } }
private static Action <object, object> createSourceSetter(Type oneSideType, Type manySideType) { var valueSetMethod = manySideType.GetProperties() .Single(p => MultiReference.IsReal(p) && MultiReference.SourceType(p) == oneSideType) .SetMethod; return(TableInfo.BuildSetAccessor(valueSetMethod)); }
internal EntityReader(Stream stream, FastDatabase dbm) { this.Stream = stream; this.info = dbm.GetTable(typeof(T)).Info; this.fieldReaders = dbm.Meta[typeof(T)]; this.recordLength = fieldReaders.Sum(r => r.FieldLength()); hiddenRefSources = info.ReferenceSources .Where(p => !MultiReference.IsReal(p)); var sourceTypes = info.EntityType.GetProperties() .Where(MultiReference.IsReal) .Select(MultiReference.SourceType); fieldSetters = fieldReaders .Select(delegate(FieldReader r) { if (r is ColumnReader) { return(info.BuildColumnSetter(r.Type, r.Name)); } else if (r is ForeignKeyReader) { return(info.BuildKeySetter(r.Type, r.Name)); } else { return(sourceTypes.Contains(r.Type) ? createSourceSetter(r.Type, info.EntityType) : (Action <object, object>)null); } }) .Select(r => r ?? emptySetter) .ToArray(); stream.Read(buffer, 0, sizeof(int)); TotalRecords = BitConverter.ToInt32(buffer, 0); }
public void CreateReaders() { if (this.lines == null) { throw new InvalidOperationException(); } int i = 0; foreach (string[] lin in lines) { if (types[i] == typeof(object)) { continue; } defs.Add(types[i], lin[2]); string[] entries = lin[2].Split(','); var array = this[types[i]] = new FieldReader[entries.Length]; for (int k = 0; k < entries.Length; k++) { string[] parts = entries[k].Split(' '); if (parts[0].StartsWith("ref")) { var referencedType = types[Int32.Parse(parts[0].Remove(0, 3))]; if (referencedType == typeof(object)) { array[k] = new EmptyReader(sizeof(int)); } else { array[k] = new ForeignKeyReader(dbm, referencedType) { Name = parts[1] } }; } else if (parts[0].StartsWith("sub=")) { //array[k] = new MultiKeyReader(dbm, types[Int32.Parse(parts[0].Remove(0, 4))]); Type referencedType = types[Int32.Parse(parts[0].Remove(0, 4))]; if (referencedType == typeof(object)) { array[k] = new EmptyReader(2 * sizeof(int)); } else { array[k] = (FieldReader)Activator.CreateInstance(typeof(MultiKeyReader <>).MakeGenericType(referencedType), dbm); try { array[k].Name = types[i].GetProperties() .SingleOrDefault(p => MultiReference.IsReal(p) && MultiReference.SourceType(p) == array[k].Type).Name; } catch (Exception e) { array[k].Name = "unknown"; } } } else { array[k] = new ColumnReader(dbm, parts[0]) { Name = parts[1] }; } } i++; } this.lines = null; }
public void SaveAll(Action <int> progressChanged) { progressChanged(0); Dictionary <String, int> stringDb = new Dictionary <string, int>(); int currentStringID = 0; while (db.Any(x => !x.Value.Sorted)) { foreach (var table in db.Values) { if (!table.Sorted) { table.SortBy(); } } } //sources = db.ToDictionary( // x0 => x0.Key, // x1 => Enumerable.Repeat((object)null, x1.Value.Count).Select(x => new List<IEntity>()).ToArray() //); //foreach (var table in db.ToArray()) // if (table.Value.First().Category != null) // foreach (var entity in table.Value) // addToSourceList(entity, entity.Category); progressChanged(10); int last = 1000; int total = db.Sum(table => table.Value.Count()); int current = 0; foreach (var table in db) { using (FileStream stream = File.Create(path + Path.DirectorySeparatorChar + table.Key.AssemblyQualifiedName + ".dat")) { stream.Write(BitConverter.GetBytes(table.Value.Count), 0, sizeof(int)); foreach (IEntity entity in table.Value) { foreach (var property in table.Key.GetProperties()) { object value = null; Type type = null; if (property.GetCustomAttributes(typeof(Column), true).Length > 0) { value = property.GetValue(entity); type = property.PropertyType; if (type == typeof(string)) { if (!stringDb.Keys.Contains(value)) { stringDb.Add(value as string, currentStringID++); } stream.Write(BitConverter.GetBytes(stringDb[value as string]), 0, sizeof(int)); } else if (type == typeof(double)) { stream.Write(BitConverter.GetBytes((double)value), 0, sizeof(double)); } else if (type == typeof(int)) { stream.Write(BitConverter.GetBytes((int)value), 0, sizeof(int)); } else if (type == typeof(uint)) { stream.Write(BitConverter.GetBytes((uint)value), 0, sizeof(uint)); } else if (type == typeof(short)) { stream.Write(BitConverter.GetBytes((short)value), 0, sizeof(short)); } else if (type == typeof(byte)) { stream.WriteByte((byte)value); } //else if (type == typeof(bool?)) //{ //} //else if (type == typeof(TimeSpan)) //{ // TimeSpan tvalue = (TimeSpan)value; // byte b1 = (byte)(tvalue.Hours + 24 * tvalue.Days); // byte b2 = (byte)tvalue.Minutes; // stream.WriteByte(b1); // stream.WriteByte(b2); //} else if (type == typeof(Tuple <bool?, TimeSpan>)) { var curValue = (Tuple <bool?, TimeSpan>)value; TimeSpan tvalue = curValue.Item2; //short s = (short)tvalue.TotalMinutes; byte b1 = (byte)(tvalue.Hours + 24 * tvalue.Days); byte b2 = (byte)tvalue.Minutes; bool?bval = curValue.Item1; byte highbit = (bval ?? false) ? (byte)0x80 : (byte)0x00; byte lowbit = bval == null ? (byte)0x40 : (byte)0x00; b1 |= (byte)(highbit | lowbit); stream.WriteByte(b1); stream.WriteByte(b2); } else if (type == typeof(DateTime)) { DateTime dvalue = (DateTime)value; byte[] yearBytes = BitConverter.GetBytes((short)dvalue.Year); byte[] bytes = new byte[] { yearBytes[0], yearBytes[1], (byte)dvalue.Month, (byte)dvalue.Day }; stream.Write(bytes, 0, bytes.Length); } else { throw new Exception("Column type not supported."); } } else if (ForeignKey.Is(property) && !ForeignKey.IsHidden(property)) { value = property.GetValue(entity); type = property.PropertyType; IEntity target = (IEntity)value; stream.Write(BitConverter.GetBytes(target.ID), 0, sizeof(int)); } else if (MultiReference.IsReal(property)) { Type propType = property.PropertyType.GetGenericArguments()[0]; var currentSources = sources[table.Key][entity.ID - 1].Where(e => e.GetType() == propType); stream.Write(BitConverter.GetBytes(currentSources.Count() > 0 ? currentSources.Min(s => s.ID) : 0), 0, sizeof(int)); stream.Write(BitConverter.GetBytes(currentSources.Count()), 0, sizeof(int)); } } } if (last-- == 0) { last = 1000; current += 1001; progressChanged(10 + (int)(current * 100 / total * 0.9)); } } } using (StreamWriter stream = new StreamWriter(File.Create(path + Path.DirectorySeparatorChar + "strings.txt"))) { var array = stringDb.ToArray().OrderBy(x => x.Value); stream.WriteLine(stringDb.Count); foreach (var str in array) { stream.WriteLine(stringTransformation(str.Key)); } } using (File.Create(path + Path.DirectorySeparatorChar + "database_exists")); }