aboutsummaryrefslogtreecommitdiff
path: root/docker/crupest-api/CrupestApi
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-12-10 15:07:12 +0800
committercrupest <crupest@outlook.com>2022-12-20 20:32:53 +0800
commit8c478bb1a07a55b9056ada029e0d6f9fe34d8d38 (patch)
treee739a8e449a1fd021a3118d9ccfb277d3f02b062 /docker/crupest-api/CrupestApi
parentddce7fb5891d97eb66960687fe1fea4cb0bd7c94 (diff)
downloadcrupest-8c478bb1a07a55b9056ada029e0d6f9fe34d8d38.tar.gz
crupest-8c478bb1a07a55b9056ada029e0d6f9fe34d8d38.tar.bz2
crupest-8c478bb1a07a55b9056ada029e0d6f9fe34d8d38.zip
Develop secret api. v23
Diffstat (limited to 'docker/crupest-api/CrupestApi')
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs13
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs10
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs33
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs15
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs3
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs45
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs24
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs11
8 files changed, 100 insertions, 54 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs
index 56ae06f..b9ec03e 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs
@@ -23,4 +23,17 @@ public class ColumnTypeInfoTest
Assert.Equal(value, typeInfo.ConvertFromDatabase(value));
Assert.Equal(value, typeInfo.ConvertToDatabase(value));
}
+
+ [Fact]
+ public void DateTimeColumnTypeTest()
+ {
+ var dateTimeColumnTypeInfo = _provider.Get(typeof(DateTime));
+ Assert.Equal(typeof(DateTime), dateTimeColumnTypeInfo.ClrType);
+ Assert.Equal(typeof(string), dateTimeColumnTypeInfo.DatabaseClrType);
+
+ var dateTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ var dateTimeString = "2000-01-01T00:00:00Z";
+ Assert.Equal(dateTimeString, dateTimeColumnTypeInfo.ConvertToDatabase(dateTime));
+ Assert.Equal(dateTime, dateTimeColumnTypeInfo.ConvertFromDatabase(dateTimeString));
+ }
}
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs
index c019e19..72b6218 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs
@@ -4,6 +4,8 @@ namespace CrupestApi.Commons.Crud.Tests;
public class SqlCompareHelper
{
+ private static List<char> SymbolTokens = new List<char>() { '(', ')', ';' };
+
public static List<string> SqlExtractWords(string? sql, bool toLower = true)
{
var result = new List<string>();
@@ -27,14 +29,14 @@ public class SqlCompareHelper
wordBuilder = null;
}
}
- else if (sql[current] == ';')
+ else if (SymbolTokens.Contains(sql[current]))
{
if (wordBuilder is not null)
{
result.Add(wordBuilder.ToString());
wordBuilder = null;
}
- result.Add(";");
+ result.Add(sql[current].ToString());
}
else
{
@@ -75,9 +77,9 @@ public class SqlCompareHelper
[Fact]
public void TestSqlExtractWords()
{
- var sql = "SELECT * FROM TableName WHERE id = @abcd;";
+ var sql = "SELECT * FROM TableName WHERE (id = @abcd);";
var words = SqlExtractWords(sql);
- Assert.Equal(new List<string> { "select", "*", "from", "tablename", "where", "id", "=", "@abcd", ";" }, words);
+ Assert.Equal(new List<string> { "select", "*", "from", "tablename", "where", "(", "id", "=", "@abcd", ")", ";" }, words);
}
}
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 d82c70f..c6791c6 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs
@@ -1 +1,34 @@
+using Xunit.Abstractions;
+
namespace CrupestApi.Commons.Crud.Tests;
+
+public class TableInfoTest
+{
+ private static TableInfoFactory TableInfoFactory = new TableInfoFactory(new ColumnTypeProvider());
+
+ private TableInfo _tableInfo;
+
+ public TableInfoTest()
+ {
+ _tableInfo = TableInfoFactory.Get(typeof(TestEntity));
+ }
+
+ [Fact]
+ public void TestColumnCount()
+ {
+ Assert.Equal(4, _tableInfo.ColumnInfos.Count);
+ Assert.Equal(3, _tableInfo.ColumnProperties.Count);
+ Assert.Equal(1, _tableInfo.NonColumnProperties.Count);
+ }
+
+ [Fact]
+ public void GenerateSelectSqlTest()
+ {
+ var (sql, parameters) = _tableInfo.GenerateSelectSql(WhereClause.Create().Eq("Name", "Hello"));
+ var parameterName = parameters.ParameterNames.First();
+
+ // TODO: Is there a way to auto detect parameters?
+ SqlCompareHelper.SqlEqual($"SELECT * FROM TestEntity WHERE (Name = @{parameterName})", sql);
+ Assert.Equal("Hello", parameters.Get<string>(parameterName));
+ }
+}
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs
new file mode 100644
index 0000000..ca84d5a
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs
@@ -0,0 +1,15 @@
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class TestEntity
+{
+ [Column(NotNull = true)]
+ public string Name { get; set; } = default!;
+
+ [Column(NotNull = true)]
+ public int Age { get; set; }
+
+ [Column]
+ public float? Height { get; set; }
+
+ public string NonColumn { get; set; } = "Not A Column";
+}
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs
index d278d23..88b5ced 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs
@@ -45,6 +45,7 @@ public class ColumnInfo
public ColumnInfo(TableInfo table, PropertyInfo propertyInfo, IColumnTypeProvider typeProvider)
{
Table = table;
+ PropertyInfo = propertyInfo;
ColumnType = typeProvider.Get(propertyInfo.PropertyType);
var columnAttribute = propertyInfo.GetCustomAttribute<ColumnAttribute>();
@@ -103,7 +104,7 @@ public class ColumnInfo
{
object? value = Metadata.GetValueOrDefault(ColumnMetadataKeys.ColumnName);
Debug.Assert(value is null || value is string);
- return (string?)value ?? PropertyInfo?.Name ?? throw new Exception("Failed to get column name.");
+ return ((string?)value ?? PropertyInfo?.Name) ?? throw new Exception("Failed to get column name.");
}
}
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs
index 7591271..c678e0e 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs
@@ -77,11 +77,6 @@ public interface IColumnTypeInfo
};
}
- JsonConverter? JsonConverter
- {
- get { return null; }
- }
-
// You must override this method if ClrType != DatabaseClrType
object? ConvertFromDatabase(object? databaseValue)
{
@@ -110,47 +105,28 @@ public class SimpleColumnTypeInfo<T> : IColumnTypeInfo
public class DateTimeColumnTypeInfo : IColumnTypeInfo
{
- private DateTimeJsonConverter _jsonConverter = new DateTimeJsonConverter();
-
public Type ClrType => typeof(DateTime);
public Type DatabaseClrType => typeof(string);
- public JsonConverter JsonConverter => _jsonConverter;
-
public object? ConvertToDatabase(object? value)
{
if (value is null) return null;
Debug.Assert(value is DateTime);
- return ((DateTime)value).ToUniversalTime().ToString("sZ");
+ return ((DateTime)value).ToUniversalTime().ToString("s") + "Z";
}
public object? ConvertFromDatabase(object? databaseValue)
{
if (databaseValue is null) return null;
Debug.Assert(databaseValue is string);
- return DateTime.ParseExact((string)databaseValue, "sZ", null, DateTimeStyles.AssumeUniversal);
- }
-}
-
-public class DateTimeJsonConverter : JsonConverter<DateTime>
-{
- public override bool HandleNull => false;
-
- public override bool CanConvert(Type typeToConvert)
- {
- return typeToConvert == typeof(DateTime);
- }
-
- public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- var s = reader.GetString();
- if (s is null) throw new Exception("Can't convert null to DateTime.");
- return DateTime.ParseExact(s, "uZ", null, DateTimeStyles.AssumeUniversal);
- }
-
- public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
- {
- writer.WriteStringValue(value.ToUniversalTime().ToString("uZ"));
+ var databaseString = (string)databaseValue;
+ var dateTimeStyles = DateTimeStyles.None;
+ if (databaseString.Length > 0 && databaseString[^1] == 'Z')
+ {
+ databaseString = databaseString.Substring(0, databaseString.Length - 1);
+ dateTimeStyles = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal;
+ }
+ return DateTime.ParseExact(databaseString, "s", null, dateTimeStyles);
}
}
@@ -171,6 +147,7 @@ public class ColumnTypeProvider : IColumnTypeProvider
_typeMap.Add(IColumnTypeInfo.DateTimeColumnTypeInfo.ClrType, IColumnTypeInfo.DateTimeColumnTypeInfo);
}
+ // This is thread-safe.
public IColumnTypeInfo Get(Type clrType)
{
if (_typeMap.TryGetValue(clrType, out var typeInfo))
@@ -179,7 +156,7 @@ public class ColumnTypeProvider : IColumnTypeProvider
}
else
{
- if (clrType == typeof(Nullable<>))
+ if (clrType.IsGenericType && clrType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
clrType = clrType.GetGenericArguments()[0];
return Get(clrType);
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs
index 9977465..28dc1ad 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/TableInfo.cs
@@ -35,7 +35,7 @@ public class TableInfo
foreach (var property in properties)
{
- if (PropertyIsColumn(property))
+ if (CheckPropertyIsColumn(property))
{
var columnInfo = new ColumnInfo(this, property, _columnTypeProvider);
columnInfos.Add(columnInfo);
@@ -89,7 +89,7 @@ public class TableInfo
public IReadOnlyList<PropertyInfo> NonColumnProperties { get; }
public IReadOnlyList<string> ColumnNameList => _lazyColumnNameList.Value;
- protected bool PropertyIsColumn(PropertyInfo property)
+ protected bool CheckPropertyIsColumn(PropertyInfo property)
{
var columnAttribute = property.GetCustomAttribute<ColumnAttribute>();
if (columnAttribute is null) return false;
@@ -469,17 +469,21 @@ public class TableInfoFactory : ITableInfoFactory
_columnTypeProvider = columnTypeProvider;
}
+ // This is thread-safe.
public TableInfo Get(Type type)
{
- if (_cache.TryGetValue(type, out var tableInfo))
+ lock (_cache)
{
- return tableInfo;
- }
- else
- {
- tableInfo = new TableInfo(type, _columnTypeProvider);
- _cache.Add(type, tableInfo);
- return tableInfo;
+ if (_cache.TryGetValue(type, out var tableInfo))
+ {
+ return tableInfo;
+ }
+ else
+ {
+ tableInfo = new TableInfo(type, _columnTypeProvider);
+ _cache.Add(type, tableInfo);
+ return tableInfo;
+ }
}
}
}
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs
index 8ae2c01..98fe49d 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/WhereClause.cs
@@ -22,6 +22,12 @@ public class CompositeWhereClause : IWhereClause
public bool ParenthesesSubclause { get; }
public List<IWhereClause> Subclauses { get; }
+ public CompositeWhereClause Eq(string column, object? value)
+ {
+ Subclauses.Add(SimpleCompareWhereClause.Eq(column, value));
+ return this;
+ }
+
public (string sql, DynamicParameters parameters) GenerateSql(string? dbProviderId = null)
{
var parameters = new DynamicParameters();
@@ -174,9 +180,4 @@ public class WhereClause : AndWhereClause
{
Subclauses.Add(subclause);
}
-
- public void Eq(string column, object? value)
- {
- Subclauses.Add(SimpleCompareWhereClause.Eq(column, value));
- }
}