diff options
Diffstat (limited to 'docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud')
7 files changed, 69 insertions, 22 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs index 3b095b2..3d5c652 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs @@ -15,7 +15,12 @@ public class ColumnInfo      public ColumnInfo(TableInfo table, IColumnMetadata metadata, Type clrType, IColumnTypeProvider typeProvider, ILoggerFactory loggerFactory)      {          _logger = loggerFactory.CreateLogger<ColumnInfo>(); -        _logger.LogInformation("Create column {} without corresponding property.", ColumnName); +        if (metadata is null) +            throw new ArgumentException("You must specify metadata for non-property column."); +        if (metadata.TryGetValue(ColumnMetadataKeys.ColumnName, out var columnName)) +            _logger.LogInformation("Create column without property.", columnName); +        else +            throw new ArgumentException("You must specify name in metadata for non-property column.");          Table = table;          _metadata.Add(metadata); @@ -28,7 +33,7 @@ public class ColumnInfo      public ColumnInfo(TableInfo table, PropertyInfo propertyInfo, IColumnTypeProvider typeProvider, ILoggerFactory loggerFactory)      {          _logger = loggerFactory.CreateLogger<ColumnInfo>(); -        _logger.LogInformation("Create column {} with corresponding property.", ColumnName); +        _logger.LogInformation("Create column with property {}.", propertyInfo.Name);          Table = table;          PropertyInfo = propertyInfo; @@ -90,7 +95,7 @@ public class ColumnInfo              if (value is null)              {                  string methodName = ColumnName + "DefaultValueGenerator"; -                result = Table.EntityType.GetMethod(methodName, BindingFlags.Static); +                result = Table.EntityType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static);              }              else              { @@ -131,7 +136,28 @@ public class ColumnInfo      public object? InvokeDefaultValueGenerator()      { -        return DefaultValueGeneratorMethod?.Invoke(null, new object?[] { this }); +        var method = this.DefaultValueGeneratorMethod; +        if (method is null) +        { +            _logger.LogInformation("Try to invoke default value generator for column {} but it does not exist.", ColumnName); +            return null; +        } +        var parameters = method.GetParameters(); +        if (parameters.Length == 0) +        { +            return method.Invoke(null, new object?[0]); +        } +        else if (parameters.Length == 1) +        { +            if (parameters[0].ParameterType != typeof(ColumnInfo)) +                throw new Exception("The default value generator method can only have a parameter of type ColumnInfo."); +            return method.Invoke(null, new object?[] { this }); +        } +        else +        { +            throw new Exception("The default value generator method can only have 0 or 1 parameter."); +        } +      }      public string GenerateCreateTableColumnString(string? dbProviderId = null) diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs index a92eb66..abae774 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs @@ -82,11 +82,11 @@ public class CrudService<TEntity> : IDisposable where TEntity : class          return result;      } -    public string Create(TEntity entity) +    public object Create(TEntity entity)      {          var insertClause = ConvertEntityToInsertClauses(entity);          var key = _table.Insert(_dbConnection, insertClause); -        return (string)key; +        return key;      }      public IUpdateClause ConvertEntityToUpdateClauses(TEntity entity, UpdateBehavior behavior) diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/DbConnectionFactory.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/DbConnectionFactory.cs index 85b818b..701622c 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/DbConnectionFactory.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/DbConnectionFactory.cs @@ -27,7 +27,9 @@ public class SqliteConnectionFactory : IDbConnectionFactory              Mode = SqliteOpenMode.ReadWriteCreate          }.ToString(); -        return new SqliteConnection(connectionString); +        var connection = new SqliteConnection(connectionString); +        connection.Open(); +        return connection;      }      public bool ShouldDisposeConnection => true; @@ -55,6 +57,7 @@ public class SqliteMemoryConnectionFactory : IDbConnectionFactory, IDisposable              connection = new SqliteConnection(connectionString);              _connections.Add(name, connection); +            connection.Open();              return connection;          }      } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/InsertClause.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/InsertClause.cs index 7645b09..a880e66 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/InsertClause.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/InsertClause.cs @@ -56,7 +56,7 @@ public class InsertClause : IInsertClause      public string GenerateColumnListSql(string? dbProviderId = null)      { -        return string.Join(", ", Items.Where(i => i.Value is not null).Select(i => i.ColumnName)); +        return string.Join(", ", Items.Select(i => i.ColumnName));      }      public (string sql, ParamList parameters) GenerateValueListSql(string? dbProviderId = null) @@ -66,7 +66,6 @@ public class InsertClause : IInsertClause          for (var i = 0; i < Items.Count; i++)          {              var item = Items[i]; -            if (item.Value is null) continue;              var parameterName = parameters.AddRandomNameParameter(item.Value, item.ColumnName);              sb.Append($"@{parameterName}");              if (i != Items.Count - 1) diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/OrderByClause.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/OrderByClause.cs index 0a43c67..734d044 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/OrderByClause.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/OrderByClause.cs @@ -20,7 +20,8 @@ public class OrderByItem  public interface IOrderByClause : IClause  {      List<OrderByItem> Items { get; } -    (string sql, ParamList parameters) GenerateSql(string? dbProviderId = null); +    // Contains "ORDER BY" keyword! +    string GenerateSql(string? dbProviderId = null);  }  public class OrderByClause : IOrderByClause @@ -42,8 +43,8 @@ public class OrderByClause : IOrderByClause          return Items.Select(x => x.ColumnName).ToList();      } -    public (string sql, ParamList parameters) GenerateSql(string? dbProviderId = null) +    public string GenerateSql(string? dbProviderId = null)      { -        return ("ORDER BY " + string.Join(", ", Items.Select(i => i.GenerateSql())), new ParamList()); +        return "ORDER BY " + string.Join(", ", Items.Select(i => i.GenerateSql()));      }  } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs index c1f647b..62ebc4a 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs @@ -153,6 +153,17 @@ public class TableInfo          throw new KeyNotFoundException("No such column with given name.");      } +    public void CheckGeneratedColumnHasGenerator() +    { +        foreach (var column in Columns) +        { +            if (column.IsGenerated && column.DefaultValueGeneratorMethod is null) +            { +                throw new Exception($"Column '{column.ColumnName}' is generated but has no generator."); +            } +        } +    } +      public void CheckValidity()      {          // Check if there is only one primary key. @@ -183,6 +194,8 @@ public class TableInfo                  throw new Exception($"Two columns have the same sql name '{column.ColumnName}'.");              sqlNameSet.Add(column.ColumnName);          } + +        CheckGeneratedColumnHasGenerator();      }      public string GenerateCreateIndexSql(string? dbProviderId = null) @@ -275,7 +288,7 @@ CREATE TABLE {tableName}(          if (whereClause is not null)          { -            result.Append(' '); +            result.Append(" WHERE ");              var (whereSql, whereParameters) = whereClause.GenerateSql(dbProviderId);              parameters.AddRange(whereParameters);              result.Append(whereSql); @@ -284,8 +297,7 @@ CREATE TABLE {tableName}(          if (orderByClause is not null)          {              result.Append(' '); -            var (orderBySql, orderByParameters) = orderByClause.GenerateSql(dbProviderId); -            parameters.AddRange(orderByParameters); +            var orderBySql = orderByClause.GenerateSql(dbProviderId);              result.Append(orderBySql);          } @@ -430,19 +442,24 @@ CREATE TABLE {tableName}(      public virtual TResult MapDynamicTo<TResult>(dynamic d)      { -        var result = Activator.CreateInstance<TResult>(); +        var dict = (IDictionary<string, object?>)d; -        Type dynamicType = d.GetType(); +        var result = Activator.CreateInstance<TResult>();          Type resultType = typeof(TResult);          foreach (var column in Columns)          { -            var dynamicProperty = dynamicType.GetProperty(column.ColumnName); -            // TODO: Maybe we can do better to get result property in case ColumnName is set to another value.              var resultProperty = resultType.GetProperty(column.ColumnName); -            if (dynamicProperty is not null && resultProperty is not null) +            if (dict.ContainsKey(column.ColumnName) && resultProperty is not null)              { -                resultProperty.SetValue(result, dynamicProperty.GetValue(d)); +                if (dict[column.ColumnName] is null) +                { +                    resultProperty.SetValue(result, null); +                    continue; +                } +                object? value = Convert.ChangeType(dict[column.ColumnName], column.ColumnType.DatabaseClrType); +                value = column.ColumnType.ConvertFromDatabase(value); +                resultProperty.SetValue(result, value);              }          } @@ -530,7 +547,7 @@ CREATE TABLE {tableName}(              }          } -        var (sql, parameters) = GenerateInsertSql(insert); +        var (sql, parameters) = GenerateInsertSql(realInsert);          dbConnection.Execute(sql, ConvertParameters(parameters)); diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs index bf3d8b1..de69f2f 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs @@ -4,6 +4,7 @@ namespace CrupestApi.Commons.Crud;  public interface IWhereClause : IClause  { +    // Does not contain "WHERE" keyword!      (string sql, ParamList parameters) GenerateSql(string? dbProviderId = null);  }  | 
