Example #1
0
        public TypeDefinition(Type type)
        {
            if (DefinitionCache.ContainsKey(type))
            {
                Definition = DefinitionCache[type];
                return;
            }

            Definition = new DefinitionCacheItem();
            ParseType(type);

            DefinitionCache[type] = Definition;
        }
Example #2
0
        /// <summary>
        /// Loads the necessary command definitions to create a backing table and
        /// perform CRUD operations with models.
        /// </summary>
        private void LoadDefinitions()
        {
            var dbSetType = GetType();

            if (DefinitionCache.ContainsKey(dbSetType))
            {
                var cache = DefinitionCache[dbSetType];
                TableName        = cache.TableName;
                TableDefinition  = cache.TableDefinition;
                SelectDefinition = cache.SelectDefinition;
                InsertDefinition = cache.InsertDefinition;
                UpdateDefinition = cache.UpdateDefinition;
                DeleteDefinition = cache.DeleteDefinition;
                return;
            }

            var createBuilder = new StringBuilder();
            var indexBuilder  = new List <string>();

            var publicInstanceFlags = BindingFlags.Instance | BindingFlags.Public;
            var properties          = typeof(T).GetProperties(publicInstanceFlags);
            var propertyNames       = new List <string>();

            // Start off with the table name
            var tableName      = nameof(T);
            var tableAttribute = typeof(T).GetTypeInfo().GetCustomAttribute <TableAttribute>();

            if (tableAttribute != null)
            {
                tableName = tableAttribute.Name;
            }

            createBuilder.AppendLine($"CREATE TABLE IF NOT EXISTS [{tableName}] (");
            createBuilder.AppendLine($"    [{nameof(ILiteModel.RowId)}] INTEGER PRIMARY KEY AUTOINCREMENT,");

            foreach (var property in properties)
            {
                if (property.Name == nameof(ILiteModel.RowId))
                {
                    continue;
                }

                if (property.CanWrite == false)
                {
                    continue;
                }

                {
                    // Skip if not mapped
                    var notMappedAttribute = property.GetCustomAttribute <NotMappedAttribute>();
                    if (notMappedAttribute != null)
                    {
                        continue;
                    }
                }

                {
                    // Add to indexes if indexed attribute is ON
                    var indexedAttribute = property.GetCustomAttribute <LiteIndexAttribute>();
                    if (indexedAttribute != null)
                    {
                        indexBuilder.Add(
                            $"CREATE INDEX IF NOT EXISTS [IX_{tableName}_{property.Name}] ON [{tableName}] ([{property.Name}]);");
                    }
                }

                {
                    // Add to unique indexes if indexed attribute is ON
                    var uniqueIndexAttribute = property.GetCustomAttribute <LiteUniqueAttribute>();

                    if (uniqueIndexAttribute != null)
                    {
                        indexBuilder.Add(
                            $"CREATE UNIQUE INDEX IF NOT EXISTS [IX_{tableName}_{property.Name}] ON [{tableName}] ([{property.Name}]);");
                    }
                }

                propertyNames.Add(property.Name);
                var propertyType = property.PropertyType;
                var isNullable   = propertyType.GetTypeInfo().IsGenericType&&
                                   propertyType.GetGenericTypeDefinition() == typeof(Nullable <>);
                if (isNullable)
                {
                    propertyType = Nullable.GetUnderlyingType(propertyType);
                }
                var nullStatement = isNullable ? "NULL" : "NOT NULL";

                if (propertyType == typeof(string))
                {
                    var stringLength = 4096;
                    {
                        var stringLengthAttribute = property.GetCustomAttribute <StringLengthAttribute>();

                        if (stringLengthAttribute != null)
                        {
                            stringLength = stringLengthAttribute.MaximumLength;
                        }
                    }

                    isNullable = property.GetCustomAttribute <RequiredAttribute>() == null;

                    nullStatement = isNullable ? "NULL" : "NOT NULL";
                    if (stringLength != 4096)
                    {
                        var checkLength = $"length({property.Name})<={stringLength}";
                        createBuilder.AppendLine(
                            $"    [{property.Name}] NVARCHAR({stringLength}) {nullStatement} CHECK({checkLength}),");
                    }
                    else
                    {
                        createBuilder.AppendLine($"    [{property.Name}] NVARCHAR({stringLength}) {nullStatement},");
                    }
                }
                else if (propertyType.GetTypeInfo().IsValueType)
                {
                    if (TypeMappings.ContainsKey(propertyType))
                    {
                        createBuilder.AppendLine($"    [{property.Name}] {TypeMappings[propertyType]} {nullStatement},");
                    }
                    else
                    {
                        createBuilder.AppendLine($"    [{property.Name}] TEXT {nullStatement},");
                    }
                }
                else if (propertyType == typeof(byte[]))
                {
                    createBuilder.AppendLine($"    [{property.Name}] BLOB {nullStatement},");
                }
            }

            //trim out the extra comma
            createBuilder.Remove(createBuilder.Length - System.Environment.NewLine.Length - 1, System.Environment.NewLine.Length + 1);

            createBuilder.AppendLine();
            createBuilder.AppendLine($");");

            foreach (var indexDdl in indexBuilder)
            {
                createBuilder.AppendLine(indexDdl);
            }

            var escapedColumnNames   = string.Join(", ", propertyNames.Select(p => $"[{p}]").ToArray());
            var parameterColumnNames = string.Join(", ", propertyNames.Select(p => $"@{p}").ToArray());
            var keyValueColumnNames  = string.Join(", ", propertyNames.Select(p => $"[{p}] = @{p}").ToArray());

            TableName       = tableName;
            TableDefinition = createBuilder.ToString();

            SelectDefinition = $"SELECT [{nameof(ILiteModel.RowId)}], {escapedColumnNames} FROM [{tableName}]";
            InsertDefinition =
                $"INSERT INTO [{tableName}] ({escapedColumnNames}) VALUES ({parameterColumnNames}); SELECT last_insert_rowid();";
            UpdateDefinition =
                $"UPDATE [{tableName}] SET {keyValueColumnNames}  WHERE [{nameof(ILiteModel.RowId)}] = @{nameof(ILiteModel.RowId)}";
            DeleteDefinition =
                $"DELETE FROM [{tableName}] WHERE [{nameof(ILiteModel.RowId)}] = @{nameof(ILiteModel.RowId)}";

            DefinitionCache[dbSetType] = new DefinitionCacheItem
            {
                TableName        = TableName,
                TableDefinition  = TableDefinition,
                SelectDefinition = SelectDefinition,
                InsertDefinition = InsertDefinition,
                UpdateDefinition = UpdateDefinition,
                DeleteDefinition = DeleteDefinition
            };
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LiteDbSet{T}"/> class.
 /// </summary>
 public LiteDbSet()
 {
     _tableDefinition = new TypeDefinition(typeof(T)).Definition;
 }