Skip to content

Commit

Permalink
add. CUD statement build (#162)
Browse files Browse the repository at this point in the history
* fixed. 修复CUD模块中自动生成的SQL语句,在Oracle下提示ORA-00933命令未正确结束的错误。原因是SQL语句结束处,加了分号。

* fixed. 当使用CUD模块,没有xml配置项时,会导致缓存无法开启。移除对SqlMaps的缓存配置项检查。

* 移除注释的代码。

* 动态插入时,自动生成Statement配置信息。

* fixed. CUD,在执行时,把Statement加入到内存中,已能和缓存产生完整交互。
added. 添加的CUD默认Statement.SqlId,用于FlushOnExecutes

* 1. 优化CUDStatement的默认名称的引用
2. 添加CUDCacheAttribute,把默认的CUD操作设置为刷新缓存。

* 优化Statement的使用。

* add. CUD statement build

* commit unit test

* 优化sql生成过程

* 完善insert和update的语法构成方式。

* fix. insert and update CUD invalid.

* 移除过期的代码。

* add. DyRepository缓存加载
  • Loading branch information
gmij authored Apr 13, 2022
1 parent 8c7182c commit a51d58f
Show file tree
Hide file tree
Showing 11 changed files with 418 additions and 220 deletions.
8 changes: 7 additions & 1 deletion src/SmartSql.DIExtension/DyRepositoryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,13 @@ public static SmartSqlDIBuilder AddRepositoryFromAssembly(this SmartSqlDIBuilder
{
scope = templateParser.Parse(type.Name);
}
return factory.CreateInstance(type, sqlMapper, scope);
var instance = factory.CreateInstance(type, sqlMapper, scope);
if (instance.IsDyRepository())
{
sqlMapper.SmartSqlConfig.CacheManager.Reset();
}
return instance;
});
}
return builder;
Expand Down
11 changes: 11 additions & 0 deletions src/SmartSql.DyRepository/Annotations/CacheAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using SmartSql.CUD;
using System;

namespace SmartSql.DyRepository.Annotations
Expand All @@ -22,4 +23,14 @@ public CacheAttribute(string id, string type)

public int CacheSize { get; set; } = 100;
}

[AttributeUsage(AttributeTargets.Interface, AllowMultiple = true)]
public class CUDCacheAttribute : CacheAttribute
{
public CUDCacheAttribute(string id, string type):base(id, type)
{
FlushOnExecutes = CUDStatementName.DefaultFlushOnExecutes;
}

}
}
28 changes: 25 additions & 3 deletions src/SmartSql.Test.Unit/CUD/CUDConfigBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ public void Build()
var configBuilder = new CUDConfigBuilder(entityTypeList);
var smartSqlConfig = configBuilder.Build();
Assert.NotNull(smartSqlConfig);
//TODO check CUD Statement
var maps = smartSqlConfig.SqlMaps;
foreach (var map in maps)
{
var scope = map.Key;
var v = map.Value;
foreach (var statement in v.Statements)
{
Console.WriteLine($"class {scope}.{statement.Value.Id} found");
}
Assert.Equal(5, v.Statements.Count);
}
}

[Fact]
Expand All @@ -31,13 +41,25 @@ public void BuildWhenParentIsXmlConfigBuilder()
var entityTypeList = TypeScan.Scan(new TypeScanOptions
{
AssemblyString = "SmartSql.Test",
Filter = type => type.Namespace == "SmartSql.Test.Entities"
Filter = type => type.FullName == "SmartSql.Test.Entities.WebMenu"
});
var configBuilder = new CUDConfigBuilder(xmlConfigBuilder, entityTypeList);
var smartSqlConfig = configBuilder.Build();
Assert.NotNull(smartSqlConfig);
//TODO check CUD Statement

var maps = smartSqlConfig.SqlMaps;
foreach (var map in maps)
{
if (map.Key != "WebMenu")
continue;
var scope = map.Key;
var v = map.Value;
foreach (var statement in v.Statements)
{
Console.WriteLine($"class {scope}.{statement.Value.Id} found");
}
Assert.Equal(6, v.Statements.Count);
}
}
}
}
40 changes: 40 additions & 0 deletions src/SmartSql.Test/Entities/WebMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using SmartSql.Annotations;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace SmartSql.Test.Entities
{
public class WebMenu
{
[Column("MENUID", IsPrimaryKey = true)]
[DisplayName("菜单ID")]
public string MenuId { get; set; }

[Column("MENUHREF")]
[DisplayName("菜单链接")]
public string MenuHref { get; set; }

[Column("MENUNAME")]
[DisplayName("菜单标题")]
public string MenuName { get; set; }

[Column("TARGET")]
[DisplayName("打开方式")]
public string Target { get; set; }

[Column("OWNERID")]
[DisplayName("上级菜单")]
public string ParentId { get; set; }

[Column("RIGHT")]
[DisplayName("权限")]
public string Right { get; set; } = "N";

[Column("ORDERBY")]
[DisplayName("排序")]
public int? OrderBy { get; set; } = 999;

}
}
23 changes: 21 additions & 2 deletions src/SmartSql/CUD/CUDConfigBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using SmartSql.ConfigBuilder;
using SmartSql.Configuration;
using SmartSql.Reflection.TypeConstants;
Expand All @@ -12,16 +14,20 @@ public class CUDConfigBuilder : IConfigBuilder
public SmartSqlConfig SmartSqlConfig { get; private set; }
public IConfigBuilder Parent { get; }
private readonly IEnumerable<Type> _entityTypeList;
private ILoggerFactory _loggerFactory;
private ILogger _logger;

public CUDConfigBuilder(IEnumerable<Type> entityTypeList)
: this(new NativeConfigBuilder(new SmartSqlConfig()), entityTypeList)
{
}

public CUDConfigBuilder(IConfigBuilder parent, IEnumerable<Type> entityTypeList)
public CUDConfigBuilder(IConfigBuilder parent, IEnumerable<Type> entityTypeList, ILoggerFactory loggerFactory = null)
{
Parent = parent;
_entityTypeList = entityTypeList;
_loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
_logger = _loggerFactory.CreateLogger<XmlConfigBuilder>();
}

public SmartSqlConfig Build()
Expand All @@ -33,6 +39,10 @@ public SmartSqlConfig Build()

SmartSqlConfig = Parent.Build();



var sqlGen = new CUDSqlGenerator(SmartSqlConfig);

foreach (var entityType in _entityTypeList)
{
var scope = EntityMetaDataCacheType.GetTableName(entityType);
Expand All @@ -51,7 +61,16 @@ public SmartSqlConfig Build()
};
SmartSqlConfig.SqlMaps.Add(scope, sqlMap);
}
//TODO Generate CUD Statement based on Type
var result = sqlGen.Generate(sqlMap, entityType);
foreach (var statement in result)
{
if (sqlMap.Statements.ContainsKey(statement.Key))
{
_logger.LogDebug("{0} Exists, CUD module Skip this Statement. Continue", statement.Key);
continue;
}
sqlMap.Statements.Add(statement.Key, statement.Value);
}
}

Initialized = true;
Expand Down
196 changes: 196 additions & 0 deletions src/SmartSql/CUD/CUDSqlGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
using SmartSql.Annotations;
using SmartSql.Configuration;
using SmartSql.Configuration.Tags;
using SmartSql.DataSource;
using SmartSql.Reflection.TypeConstants;
using SmartSql.Utils;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace SmartSql.CUD
{
public class CUDSqlGenerator : ICUDSqlGenerator
{


private IDictionary<string, Func<GeneratorParams, Statement>> _generatorFuncList;
private DbProvider _provider;
private StatementAnalyzer _analyzer;


public CUDSqlGenerator(SmartSqlConfig config)
{
_generatorFuncList = new Dictionary<string, Func<GeneratorParams, Statement>>
{
{ CUDStatementName.GetById, BuildGetEntity},
{ CUDStatementName.Insert, BuildInsert },
{ CUDStatementName.InsertReturnId, BuildInsertReturnId },
{ CUDStatementName.Update, BuildUpdate },
{ CUDStatementName.DeleteById, BuildDeleteById },
{ CUDStatementName.DeleteAll, BuildDeleteAll },
{ CUDStatementName.DeleteMany, BuildDeleteMany },
};
_provider = config.Database.DbProvider;
_analyzer = new StatementAnalyzer();
}



private Statement BuildStatement(string statementId, string sql, SqlMap sqlMap)
{
return new Statement()
{
SqlMap = sqlMap,
Id = statementId,
CommandType = System.Data.CommandType.Text,
StatementType = _analyzer.Analyse(sql),
SqlTags = new List<ITag>
{
new SqlText(sql, _provider.ParameterPrefix)
},
};
}

private Statement BuildStatement(string statementId, List<ITag> sqlTags, SqlMap sqlMap)
{
return new Statement()
{
SqlMap = sqlMap,
Id = statementId,
CommandType = System.Data.CommandType.Text,
//StatementType = _analyzer.Analyse(sql),
SqlTags = sqlTags,
};
}


public Statement BuildGetEntity(GeneratorParams gParams)
{
var sql =
$"select * From {gParams.TableName} Where {WrapColumnEqParameter(_provider, gParams.PkCol)}";

return BuildStatement(CUDStatementName.GetById, sql, gParams.Map);
}

public Statement BuildDeleteAll(GeneratorParams gParams)
{
var sql = $"delete from {gParams.TableName}";
return BuildStatement(CUDStatementName.DeleteAll, sql, gParams.Map);
}

public Statement BuildDeleteById(GeneratorParams gParams)
{
var sql =
$"Delete From {gParams.TableName} Where {WrapColumnEqParameter(_provider, gParams.PkCol)}";

return BuildStatement(CUDStatementName.DeleteById, sql, gParams.Map);
}

public Statement BuildDeleteMany(GeneratorParams gParams)
{
var sql = $"Delete From {gParams.TableName} Where {gParams.PkCol.Name} In {FormatParameterName(_provider, gParams.PkCol.Name)}";
return BuildStatement(CUDStatementName.DeleteMany, sql, gParams.Map);
}

public Statement BuildInsert(GeneratorParams gParams)
{
var cols = gParams.ColumnMaps;
string colNames = string.Empty;
string colVals = string.Empty;
foreach (var col in cols)
{
if (col.Value.IsAutoIncrement)
continue;
colNames += $",{FormatColumnName(_provider, col.Value.Name)}";
colVals += $",{FormatParameterName(_provider, col.Value.Property.Name)}";
}
var sql = $"insert into {gParams.TableName} ({colNames.Substring(1)}) values ({colVals.Substring(1)})";
return BuildStatement(CUDStatementName.Insert, sql, gParams.Map);
}

public Statement BuildInsertReturnId(GeneratorParams arg)
{
var statement = BuildInsert(arg);

if (_provider.Type == DbProviderManager.POSTGRESQL_DBPROVIDER.Type)
{
statement.SqlTags.Add(new SqlText($" ; Returning {arg.PkCol.Name};", _provider.ParameterPrefix));
}
else
{
statement.SqlTags.Add(new SqlText($"; {_provider.SelectAutoIncrement};", _provider.ParameterPrefix));
}

return statement;
}

public Statement BuildUpdate(GeneratorParams gParams)
{
var dbPrefix = _provider.ParameterPrefix;

var updateTags = new List<ITag>();
foreach (var col in gParams.ColumnMaps.Values)
{
if (col.IsPrimaryKey)
continue;
var p = new IsProperty()
{
Prepend = ",",
Property = col.Property.Name,
ChildTags = new List<ITag>()
{
new SqlText($"{WrapColumnEqParameter(_provider,col)}", dbPrefix)
}
};
updateTags.Add(p);
}

var sqlTags = new List<ITag>()
{
new SqlText($"update {gParams.TableName}", dbPrefix),
new Set()
{
ChildTags = updateTags
},
new SqlText($" where {WrapColumnEqParameter(_provider, gParams.PkCol)}", dbPrefix),
};

return BuildStatement(CUDStatementName.Update, sqlTags, gParams.Map);
}

public IDictionary<string, Statement> Generate(SqlMap map, Type entityType)
{
var statementList = new Dictionary<string, Statement>();

var gParams = new GeneratorParams(map, entityType);
if (_generatorFuncList != null && _generatorFuncList.Count > 0)
{
foreach (var item in _generatorFuncList)
{
statementList.Add($"{map.Scope}.{item.Key}", item.Value(gParams));
}
}
return statementList;
}

private static string WrapColumnEqParameter(DbProvider dbProvider, ColumnAttribute col)
{
return
$"{dbProvider.ParameterNamePrefix}{col.Name}{dbProvider.ParameterNameSuffix}={dbProvider.ParameterPrefix}{col.Property.Name}";
}

private static string FormatColumnName(DbProvider dbProvider, string paramName)
{
return $"{dbProvider.ParameterNamePrefix}{paramName}{dbProvider.ParameterNameSuffix}";
}

private static string FormatParameterName(DbProvider dbProvider, string paramName)
{
return $"{dbProvider.ParameterPrefix}{paramName}";
}

}
}
Loading

0 comments on commit a51d58f

Please sign in to comment.