Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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