Skip to content

Commit

Permalink
[improv] 优化MySql正向工程,一次性加载所有表的字段,加快启动速度
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Mar 7, 2024
1 parent ea0cd42 commit 46202a0
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 45 deletions.
158 changes: 114 additions & 44 deletions XCode/DataAccessLayer/Database/MySql.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public override String FormatValue(IDataColumn field, Object? value)
return base.FormatValue(field, value);
}

private static readonly Char[] _likeKeys = new[] { '\\', '\'', '\"', '%', '_' };
private static readonly Char[] _likeKeys = ['\\', '\'', '\"', '%', '_'];

/// <summary>格式化模糊搜索的字符串。处理转义字符</summary>
/// <param name="column">字段</param>
Expand Down Expand Up @@ -402,7 +402,15 @@ protected override List<IDataTable> OnGetTables(String[]? names)
var dt = ss.Query(sql, null);
if (dt.Rows == null || dt.Rows.Count == 0) return list;

var hs = new HashSet<String>(names ?? new String[0], StringComparer.OrdinalIgnoreCase);
sql = $"select * from information_schema.columns where table_schema='{db}'";
if (names != null && names.Length > 0) sql += " and table_name in ('" + names.Join("','") + "')";
var columns = ss.Query(sql, null);

sql = $"select * from information_schema.STATISTICS where table_schema='{db}'";
if (names != null && names.Length > 0) sql += " and table_name in ('" + names.Join("','") + "')";
var indexes = ss.Query(sql, null);

var hs = new HashSet<String>(names ?? [], StringComparer.OrdinalIgnoreCase);

// 所有表
foreach (var dr in dt)
Expand All @@ -416,65 +424,127 @@ protected override List<IDataTable> OnGetTables(String[]? names)
table.DbType = Database.Type;

#region 字段

sql = $"SHOW FULL COLUMNS FROM `{db}`.`{name}`";
var dcs = ss.Query(sql, null);
foreach (var dc in dcs)
if (columns.Rows != null && columns.Rows.Count > 0)
{
var field = table.CreateColumn();
foreach (var dc in columns)
{
if (dc["TABLE_NAME"] + "" != table.TableName) continue;

field.ColumnName = dc["Field"] + "";
field.RawType = dc["Type"] + "";
field.Description = dc["Comment"] + "";
var field = table.CreateColumn();

if (dc["Extra"] + "" == "auto_increment") field.Identity = true;
if (dc["Key"] + "" == "PRI") field.PrimaryKey = true;
if (dc["Null"] + "" == "YES") field.Nullable = true;
field.ColumnName = dc["COLUMN_NAME"] + "";
field.RawType = dc["COLUMN_TYPE"] + "";
field.Description = dc["COLUMN_COMMENT"] + "";

field.Length = field.RawType.Substring("(", ")").ToInt();
field.DataType = GetDataType(field);
if (dc["Extra"] + "" == "auto_increment") field.Identity = true;
if (dc["COLUMN_KEY"] + "" == "PRI") field.PrimaryKey = true;
if (dc["IS_NULLABLE"] + "" == "YES") field.Nullable = true;

if (field.DataType == null)
{
if (field.RawType.StartsWithIgnoreCase("varchar", "nvarchar")) field.DataType = typeof(String);
}
field.Length = field.RawType.Substring("(", ")").ToInt();

var type = GetDataType(field);
if (type == null)
{
if (field.RawType.StartsWithIgnoreCase("varchar", "nvarchar")) field.DataType = typeof(String);
}
else
field.DataType = type;

// MySql中没有布尔型,这里处理YN枚举作为布尔型
if (field.RawType is "enum('N','Y')" or "enum('Y','N')") field.DataType = typeof(Boolean);
// MySql中没有布尔型,这里处理YN枚举作为布尔型
if (field.RawType is "enum('N','Y')" or "enum('Y','N')") field.DataType = typeof(Boolean);

field.Fix();
field.Fix();

table.Columns.Add(field);
table.Columns.Add(field);
}
}
else
{
sql = $"SHOW FULL COLUMNS FROM `{db}`.`{name}`";
var dcs = ss.Query(sql, null);
foreach (var dc in dcs)
{
var field = table.CreateColumn();

#endregion 字段
field.ColumnName = dc["Field"] + "";
field.RawType = dc["Type"] + "";
field.Description = dc["Comment"] + "";

#region 索引
if (dc["Extra"] + "" == "auto_increment") field.Identity = true;
if (dc["Key"] + "" == "PRI") field.PrimaryKey = true;
if (dc["Null"] + "" == "YES") field.Nullable = true;

sql = $"SHOW INDEX FROM `{db}`.`{name}`";
var dis = ss.Query(sql, null);
foreach (var dr2 in dis)
{
var dname = dr2["Key_name"] + "";
var di = table.Indexes.FirstOrDefault(e => e.Name == dname) ?? table.CreateIndex();
//di.Name = dname;
di.Unique = dr2.Get<Int32>("Non_unique") == 0;
field.Length = field.RawType.Substring("(", ")").ToInt();
field.DataType = GetDataType(field);

var cname = dr2.Get<String>("Column_name");
if (cname.IsNullOrEmpty()) continue;
if (field.DataType == null)
{
if (field.RawType.StartsWithIgnoreCase("varchar", "nvarchar")) field.DataType = typeof(String);
}

var cs = new List<String>();
if (di.Columns != null && di.Columns.Length > 0) cs.AddRange(di.Columns);
cs.Add(cname);
di.Columns = cs.ToArray();
// MySql中没有布尔型,这里处理YN枚举作为布尔型
if (field.RawType is "enum('N','Y')" or "enum('Y','N')") field.DataType = typeof(Boolean);

if (di.Name == null)
{
di.Name = dname;
table.Indexes.Add(di);
field.Fix();

table.Columns.Add(field);
}
}
#endregion 字段

#region 索引
if (indexes.Rows != null && indexes.Rows.Count > 0)
{
foreach (var dr2 in indexes)
{
if (dr2["TABLE_NAME"] + "" != table.TableName) continue;

var dname = dr2["INDEX_NAME"] + "";
var di = table.Indexes.FirstOrDefault(e => e.Name == dname) ?? table.CreateIndex();
//di.Name = dname;
di.Unique = dr2.Get<Int32>("Non_unique") == 0;

var cname = dr2.Get<String>("Column_name");
if (cname.IsNullOrEmpty()) continue;

var cs = new List<String>();
if (di.Columns != null && di.Columns.Length > 0) cs.AddRange(di.Columns);
cs.Add(cname);
di.Columns = cs.ToArray();

if (di.Name == null)
{
di.Name = dname;
table.Indexes.Add(di);
}
}
}
else
{
sql = $"SHOW INDEX FROM `{db}`.`{name}`";
var dis = ss.Query(sql, null);
foreach (var dr2 in dis)
{
var dname = dr2["Key_name"] + "";
var di = table.Indexes.FirstOrDefault(e => e.Name == dname) ?? table.CreateIndex();
//di.Name = dname;
di.Unique = dr2.Get<Int32>("Non_unique") == 0;

var cname = dr2.Get<String>("Column_name");
if (cname.IsNullOrEmpty()) continue;

var cs = new List<String>();
if (di.Columns != null && di.Columns.Length > 0) cs.AddRange(di.Columns);
cs.Add(cname);
di.Columns = cs.ToArray();

if (di.Name == null)
{
di.Name = dname;
table.Indexes.Add(di);
}
}
}
#endregion 索引

// 修正关系数据
Expand Down Expand Up @@ -595,7 +665,7 @@ public override String FieldClause(IDataColumn field, Boolean onlyDefine)

protected override Boolean DatabaseExist(String databaseName)
{
var dt = GetSchema(_.Databases, new String[] { databaseName });
var dt = GetSchema(_.Databases, [databaseName]);
return dt != null && dt.Rows != null && dt.Rows.Count > 0;
}

Expand Down
23 changes: 22 additions & 1 deletion XUnitTest.XCode/DataAccessLayer/MySqlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,28 @@ public void GetTables()
var dal = DAL.Create("member_mysql");
var tables = dal.Tables;

Assert.True(tables.Count > 0);
Assert.NotEmpty(tables);

foreach (var table in tables)
{
Assert.NotEmpty(table.Columns);
foreach (var dc in table.Columns)
{
Assert.NotEmpty(dc.Name);
Assert.NotEmpty(dc.ColumnName);
Assert.NotEmpty(dc.RawType);
Assert.NotNull(dc.DataType);
Assert.NotEmpty(dc.DisplayName);
Assert.NotEmpty(dc.Description);
}

//Assert.NotEmpty(table.Indexes);
foreach (var di in table.Indexes)
{
Assert.NotEmpty(di.Name);
Assert.NotEmpty(di.Columns);
}
}

dal.SetTables(User.Meta.Table.DataTable);
}
Expand Down

0 comments on commit 46202a0

Please sign in to comment.