diff options
author | crupest <crupest@outlook.com> | 2022-12-21 16:32:38 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-12-21 16:32:38 +0800 |
commit | 839e4fea3bd11b1b7e9e212e9fc2fbd3d94a6db1 (patch) | |
tree | 7a707dea3daa2c860a0bb215fef44bbcf76f4efc | |
parent | e3510f87617cebf4d11c9bf0e5e4ba640a5741e4 (diff) | |
download | crupest-839e4fea3bd11b1b7e9e212e9fc2fbd3d94a6db1.tar.gz crupest-839e4fea3bd11b1b7e9e212e9fc2fbd3d94a6db1.tar.bz2 crupest-839e4fea3bd11b1b7e9e212e9fc2fbd3d94a6db1.zip |
Develop secret api. v54
9 files changed, 88 insertions, 26 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs index 0c42c67..b7b7ccd 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs @@ -21,11 +21,26 @@ public class CrudServiceTest [Fact] public void CrudTest() { - _crudService.Create(new TestEntity() + var key = _crudService.Create(new TestEntity() { Name = "crupest", Age = 18, }); + + Assert.Equal("crupest", key); + + var entity = _crudService.GetByKey(key); + Assert.Equal("crupest", entity.Name); + Assert.Equal(18, entity.Age); + Assert.Null(entity.Height); + Assert.NotEmpty(entity.Secret); + + var list = _crudService.GetAll(); + entity = Assert.Single(list); + Assert.Equal("crupest", entity.Name); + Assert.Equal(18, entity.Age); + Assert.Null(entity.Height); + Assert.NotEmpty(entity.Secret); } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs index 228f442..b0aa702 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs @@ -16,9 +16,9 @@ public class TableInfoTest [Fact] public void TestColumnCount() { - Assert.Equal(4, _tableInfo.Columns.Count); - Assert.Equal(3, _tableInfo.PropertyColumns.Count); - Assert.Equal(3, _tableInfo.ColumnProperties.Count); + Assert.Equal(5, _tableInfo.Columns.Count); + Assert.Equal(4, _tableInfo.PropertyColumns.Count); + Assert.Equal(4, _tableInfo.ColumnProperties.Count); Assert.Equal(1, _tableInfo.NonColumnProperties.Count); } 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); } |