Пример #1
0
        public CodeFirst()
        {
            _tables = new Dictionary <string, Table>();
            var baseType = typeof(JsonObject);
            var assembly = baseType.Assembly;

            _foreignKeys = new Dictionary <Field, ForeignKeyAttribute>();
            foreach (Type tbl in assembly.GetTypes().Where(t => t.BaseType == baseType))
            {
                if (!tbl.IsDefined(typeof(TableAttribute)))
                {
                    continue;
                }
                processTable(tbl, null);
            }
            foreach (Field fld in _foreignKeys.Keys)
            {
                ForeignKeyAttribute fk = _foreignKeys[fld];
                Table tbl = TableFor(fk.Table);
                fld.ForeignKey = new ForeignKey(tbl, tbl.Fields[0]);
            }
            foreach (Type tbl in assembly.GetTypes().Where(t => t.IsSubclassOf(baseType)))
            {
                ViewAttribute view = tbl.GetCustomAttribute <ViewAttribute>();
                if (view == null)
                {
                    continue;
                }
                processTable(tbl, view);
            }
            _foreignKeys = null;
        }
Пример #2
0
        void processTable(Type tbl, ViewAttribute view)
        {
            List <Field> fields = new List <Field>();
            // Indexes by name
            Dictionary <string, List <Tuple <int, Field> > > indexes = new Dictionary <string, List <Tuple <int, Field> > >();
            // Primary key fields by sequence
            List <Tuple <int, Field> > primary = new List <Tuple <int, Field> >();
            string primaryName = null;

            processFields(tbl, ref fields, ref indexes, ref primary, ref primaryName);
            if (primary.Count == 0)
            {
                primary.Add(new Tuple <int, Field>(0, fields[0]));
                primaryName = "PRIMARY";
            }
            List <Index> inds = new List <Index>(indexes.Keys
                                                 .OrderBy(k => k)
                                                 .Select(k => new Index(k, indexes[k]
                                                                        .OrderBy(i => i.Item1)
                                                                        .Select(i => i.Item2)
                                                                        .ToArray())));

            inds.Insert(0, new Index(primaryName, primary
                                     .OrderBy(i => i.Item1)
                                     .Select(i => i.Item2)
                                     .ToArray()));
            if (view != null)
            {
                Table updateTable = null;
                for (Type t = tbl; updateTable == null && t != typeof(JsonObject); t = t.BaseType)
                {
                    _tables.TryGetValue(Regex.Replace(t.Name, "^.*_", ""), out updateTable);
                }
                _tables[tbl.Name] = new View(tbl.Name, fields.ToArray(), inds.ToArray(), view.Sql, updateTable);
            }
            else
            {
                _tables[tbl.Name] = new Table(tbl.Name, fields.ToArray(), inds.ToArray());
            }
        }
Пример #3
0
 void processTable(Type tbl, ViewAttribute view)
 {
     List<Field> fields = new List<Field>();
     // Indexes by name
     Dictionary<string, List<Tuple<int, Field>>> indexes = new Dictionary<string, List<Tuple<int, Field>>>();
     // Primary key fields by sequence
     List<Tuple<int, Field>> primary = new List<Tuple<int, Field>>();
     string primaryName = null;
     foreach (FieldInfo field in tbl.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)) {
         if (field.IsDefined(typeof(DoNotStoreAttribute)))
             continue;
         bool nullable = field.IsDefined(typeof(NullableAttribute));
         Type pt = field.FieldType;
         decimal length = 0;
         string defaultValue = null;
         // Convert nullable types to their base type, but set nullable flag
         if (pt == typeof(bool?)) {
             pt = typeof(bool);
             nullable = true;
         } else if (pt == typeof(int?)) {
             pt = typeof(int);
             nullable = true;
         } else if (pt == typeof(decimal?)) {
             pt = typeof(decimal);
             nullable = true;
         } else if (pt == typeof(double?)) {
             pt = typeof(double);
             nullable = true;
         } else if (pt == typeof(DateTime?)) {
             pt = typeof(DateTime);
             nullable = true;
         }
         PrimaryAttribute pk = field.GetCustomAttribute<PrimaryAttribute>();
         if (pk != null)
             nullable = false;			// Primary keys may not be null
         // Set length and default value (may be overridden later by specific attributes)
         if (pt == typeof(bool)) {
             length = 1;
             defaultValue = "0";
         } else if (pt == typeof(int)) {
             length = 11;
             defaultValue = "0";
         } else if (pt == typeof(decimal)) {
             length = 10.2M;
             defaultValue = "0.00";
         } else if (pt == typeof(double)) {
             length = 10.4M;
             defaultValue = "0";
         } else if (pt == typeof(string)) {
             length = 45;
             defaultValue = "";
         }
         if (nullable)
             defaultValue = null;		// If field is nullable, null is always the default value
         LengthAttribute la = field.GetCustomAttribute<LengthAttribute>();
         if (la != null)					// Override length
             length = la.Length + la.Precision / 10M;
         DefaultValueAttribute da = field.GetCustomAttribute<DefaultValueAttribute>();
         if (da != null)					// Override default value
             defaultValue = da.Value;
         Field fld = new Field(field.Name, pt, length, nullable, pk != null && pk.AutoIncrement, defaultValue);
         if (pk != null) {
             primary.Add(new Tuple<int, Field>(pk.Sequence, fld));
             Utils.Check(primaryName == null || primaryName == pk.Name, "2 Primary keys defined on {0}", tbl.Name);
             primaryName = pk.Name;
         }
         // See if the field is in one or more indexes
         foreach (UniqueAttribute a in field.GetCustomAttributes<UniqueAttribute>()) {
             List<Tuple<int, Field>> index;
             if (!indexes.TryGetValue(a.Name, out index)) {
                 // New index
                 index = new List<Tuple<int, Field>>();
                 indexes[a.Name] = index;
             }
             // Add field to index
             index.Add(new Tuple<int, Field>(a.Sequence, fld));
         }
         // See if the field is a foreign key
         ForeignKeyAttribute fk = field.GetCustomAttribute<ForeignKeyAttribute>();
         if (fk != null)
             _foreignKeys[fld] = fk;
         fields.Add(fld);
     }
     if (primary.Count == 0) {
         // No primary key - use the first field
         primary.Add(new Tuple<int, Field>(0, fields[0]));
         primaryName = "PRIMARY";
     }
     // Build the index list
     List<Index> inds = new List<Index>(indexes.Keys
         .OrderBy(k => k)	// In name order
         .Select(k => new Index(k, indexes[k]
             .OrderBy(i => i.Item1)		// Sequence
             .Select(i => i.Item2)		// Field name
             .ToArray())));
     // Primary key is always first index.
     inds.Insert(0, new Index(primaryName, primary
             .OrderBy(i => i.Item1)
             .Select(i => i.Item2)
             .ToArray()));
     if (view != null) {
         Table updateTable = null;
         // Update table is all text after last "_"
         _tables.TryGetValue(Regex.Replace(tbl.Name, "^.*_", ""), out updateTable);
         _tables[tbl.Name] = new View(tbl.Name, fields.ToArray(), inds.ToArray(), view.Sql, updateTable);
     } else {
         _tables[tbl.Name] = new Table(tbl.Name, fields.ToArray(), inds.ToArray());
     }
 }