/// <summary> /// Executes a "create table if not exists" on the database. It also /// creates any specified indexes on the columns of the table. It uses /// a schema automatically generated from the specified type. You can /// later access this schema by calling GetMapping. /// </summary> /// <param name="ty">Type to reflect to a database table.</param> /// <returns> /// The number of entries added to the database schema. /// </returns> public int CreateTable(Type ty) { if (_tables == null) { _tables = new Dictionary <string, TableMapping> (); } TableMapping map; if (!_tables.TryGetValue(ty.FullName, out map)) { map = GetMapping(ty); _tables.Add(ty.FullName, map); } var query = "create table if not exists \"" + map.TableName + "\"(\n"; var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks)); var decl = string.Join(",\n", decls.ToArray()); query += decl; query += ")"; var count = Execute(query); if (count == 0) //Possible bug: This always seems to return 0? // Table already exists, migrate it { MigrateTable(map); } var indexes = new Dictionary <string, IndexInfo> (); foreach (var c in map.Columns) { foreach (var i in c.Indices) { var iname = i.Name ?? map.TableName + "_" + c.Name; IndexInfo iinfo; if (!indexes.TryGetValue(iname, out iinfo)) { iinfo = new IndexInfo { IndexName = iname, TableName = map.TableName, Unique = i.Unique, Columns = new List <IndexedColumn> () }; indexes.Add(iname, iinfo); } if (i.Unique != iinfo.Unique) { throw new Exception("All the columns in an index must have the same value for their Unique property"); } iinfo.Columns.Add(new IndexedColumn { Order = i.Order, ColumnName = c.Name }); } } foreach (var indexName in indexes.Keys) { var index = indexes[indexName]; const string sqlFormat = "create {3} index if not exists \"{0}\" on \"{1}\"(\"{2}\")"; var columns = String.Join("\",\"", index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray()); var sql = String.Format(sqlFormat, indexName, index.TableName, columns, index.Unique ? "unique" : ""); count += Execute(sql); } return(count); }