Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit f0a8241

Browse files
authored
Support custom order of columns when creating table (#665)
Much nicer, thx 👍
1 parent 8dbc341 commit f0a8241

File tree

5 files changed

+95
-9
lines changed

5 files changed

+95
-9
lines changed

src/ServiceStack.OrmLite.MySql/MySqlDialectProviderBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Data.Common;
5+
using System.Linq;
56
using System.Threading;
67
using System.Threading.Tasks;
78
using ServiceStack.OrmLite.MySql.Converters;

src/ServiceStack.OrmLite/FieldDefinition.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public class FieldDefinition
6262
public string CheckConstraint { get; set; }
6363

6464
public bool IsUniqueConstraint { get; set; }
65+
66+
public int Order { get; set; }
6567

6668
public ForeignKeyConstraint ForeignKey { get; set; }
6769

src/ServiceStack.OrmLite/OrmLiteConfigExtensions.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ internal static void ClearCache()
4242
}
4343

4444
internal static ModelDefinition GetModelDefinition(this Type modelType)
45-
{
45+
{
4646
if (typeModelDefinitionMap.TryGetValue(modelType, out var modelDef))
4747
return modelDef;
4848

@@ -98,6 +98,7 @@ string JoinSql(List<string> statements)
9898
var hasIdField = CheckForIdField(objProperties);
9999

100100
var i = 0;
101+
var propertyInfoIdx = 0;
101102
foreach (var propertyInfo in objProperties)
102103
{
103104
if (propertyInfo.GetIndexParameters().Length > 0)
@@ -111,7 +112,7 @@ string JoinSql(List<string> statements)
111112
var decimalAttribute = propertyInfo.FirstAttribute<DecimalLengthAttribute>();
112113
var belongToAttribute = propertyInfo.FirstAttribute<BelongToAttribute>();
113114
var referenceAttr = propertyInfo.FirstAttribute<ReferenceAttribute>();
114-
115+
115116
var isRowVersion = propertyInfo.Name == ModelDefinition.RowVersionName
116117
&& (propertyInfo.PropertyType == typeof(ulong) || propertyInfo.PropertyType == typeof(byte[]));
117118

@@ -124,7 +125,7 @@ string JoinSql(List<string> statements)
124125
var propertyType = isNullableType
125126
? Nullable.GetUnderlyingType(propertyInfo.PropertyType)
126127
: propertyInfo.PropertyType;
127-
128+
128129

129130
Type treatAsType = null;
130131

@@ -149,13 +150,13 @@ string JoinSql(List<string> statements)
149150
|| isAutoId;
150151

151152
var isAutoIncrement = isPrimaryKey && propertyInfo.HasAttributeCached<AutoIncrementAttribute>();
152-
153+
153154
if (isAutoIncrement && propertyInfo.PropertyType == typeof(Guid))
154155
throw new NotSupportedException($"[AutoIncrement] is only valid for integer properties for {modelType.Name}.{propertyInfo.Name} Guid property use [AutoId] instead");
155-
156+
156157
if (isAutoId && (propertyInfo.PropertyType == typeof(int) || propertyInfo.PropertyType == typeof(long)))
157158
throw new NotSupportedException($"[AutoId] is only valid for Guid properties for {modelType.Name}.{propertyInfo.Name} integer property use [AutoIncrement] instead");
158-
159+
159160
var aliasAttr = propertyInfo.FirstAttribute<AliasAttribute>();
160161

161162
var indexAttr = propertyInfo.FirstAttribute<IndexAttribute>();
@@ -171,6 +172,9 @@ string JoinSql(List<string> statements)
171172
var customFieldAttr = propertyInfo.FirstAttribute<CustomFieldAttribute>();
172173
var chkConstraintAttr = propertyInfo.FirstAttribute<CheckConstraintAttribute>();
173174

175+
var order = propertyInfoIdx++;
176+
if (customFieldAttr != null) order = customFieldAttr.Order;
177+
174178
var fieldDefinition = new FieldDefinition
175179
{
176180
Name = propertyInfo.Name,
@@ -187,7 +191,7 @@ string JoinSql(List<string> statements)
187191
IsUniqueIndex = isUnique,
188192
IsClustered = indexAttr?.Clustered == true,
189193
IsNonClustered = indexAttr?.NonClustered == true,
190-
IndexName = indexAttr?.Name,
194+
IndexName = indexAttr?.Name,
191195
IsRowVersion = isRowVersion,
192196
IgnoreOnInsert = propertyInfo.HasAttributeCached<IgnoreOnInsertAttribute>(),
193197
IgnoreOnUpdate = propertyInfo.HasAttributeCached<IgnoreOnUpdateAttribute>(),
@@ -213,6 +217,7 @@ string JoinSql(List<string> statements)
213217
BelongToModelName = belongToAttribute?.BelongToTableType.GetModelDefinition().ModelName,
214218
CustomFieldDefinition = customFieldAttr?.Sql,
215219
IsRefType = propertyType.IsRefType(),
220+
Order = order
216221
};
217222

218223
if (isIgnored)

src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,9 +1297,9 @@ public virtual string ResolveFragment(string sql)
12971297

12981298
public virtual string GetAutoIdDefaultValue(FieldDefinition fieldDef) => null;
12991299

1300-
public Func<ModelDefinition, List<FieldDefinition>> CreateTableFieldsStrategy { get; set; } = GetFieldDefinitions;
1300+
public Func<ModelDefinition, IEnumerable<FieldDefinition>> CreateTableFieldsStrategy { get; set; } = GetFieldDefinitions;
13011301

1302-
public static List<FieldDefinition> GetFieldDefinitions(ModelDefinition modelDef) => modelDef.FieldDefinitions;
1302+
public static IEnumerable<FieldDefinition> GetFieldDefinitions(ModelDefinition modelDef) => modelDef.FieldDefinitions.OrderBy(fd=>fd.Order);
13031303

13041304
public abstract string ToCreateSchemaStatement(string schemaName);
13051305

tests/ServiceStack.OrmLite.MySql.Tests/OrmLiteCreateTableTests.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,83 @@ public void Does_DoesColumnExist()
160160
exists = db.ColumnExists<Signal>(x => x.Code);
161161
Assert.That(exists);
162162
}
163+
164+
[Test]
165+
public void Can_create_table_with_custom_field_order()
166+
{
167+
using (var db = OpenDbConnection())
168+
{
169+
var modelDefinition = typeof(ModelWithCustomFiledOrder).GetModelMetadata();
170+
db.DropAndCreateTable<ModelWithCustomFiledOrder>();
171+
var defs=db.SqlList<(string field,string type,string @null,string key,string @default,string extra)>("desc " + modelDefinition.Name);
172+
Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Filed1),defs[0].field);
173+
Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Filed3),defs[1].field);
174+
Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Filed2), defs[2].field);
175+
Assert.AreEqual(nameof(ModelWithCustomFiledOrder.Id),defs[3].field);
176+
}
177+
}
178+
179+
[Test]
180+
public void Can_create_table_without_custom_field_order()
181+
{
182+
using (var db = OpenDbConnection())
183+
{
184+
var modelDefinition = typeof(ModelWithoutCustomFiledOrder).GetModelMetadata();
185+
db.DropAndCreateTable<ModelWithoutCustomFiledOrder>();
186+
var defs = db.SqlList<(string field, string type, string @null, string key, string @default, string extra)>("desc " + modelDefinition.Name);
187+
Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Id), defs[0].field);
188+
Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Filed1), defs[1].field);
189+
Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Filed2), defs[2].field);
190+
Assert.AreEqual(nameof(ModelWithoutCustomFiledOrder.Filed3), defs[3].field);
191+
}
192+
}
193+
194+
[Test]
195+
public void model_definition_without_custom_order()
196+
{
197+
var modelDefinition = typeof(ModelWithoutCustomFiledOrder).GetModelMetadata();
198+
Assert.AreEqual(4, modelDefinition.FieldDefinitions.Count);
199+
Assert.AreEqual(0, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Id)).Order);
200+
Assert.AreEqual(1, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed1)).Order);
201+
Assert.AreEqual(2, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed2)).Order);
202+
Assert.AreEqual(3, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed3)).Order);
203+
}
204+
205+
[Test]
206+
public void model_definition_with_custom_order()
207+
{
208+
var modelDefinition = typeof(ModelWithCustomFiledOrder).GetModelMetadata();
209+
Assert.AreEqual(4, modelDefinition.FieldDefinitions.Count);
210+
Assert.AreEqual(100, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Id)).Order);
211+
Assert.AreEqual(5, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed1)).Order);
212+
Assert.AreEqual(13, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed2)).Order);
213+
Assert.AreEqual(8, modelDefinition.FieldDefinitions.Find(fd => fd.Name == nameof(ModelWithoutCustomFiledOrder.Filed3)).Order);
214+
}
215+
216+
public class ModelWithoutCustomFiledOrder
217+
{
218+
[PrimaryKey]
219+
[AutoIncrement]
220+
public int Id { get; set; }
221+
222+
public int Filed1 { get; set; }
223+
public string Filed2 { get; set; }
224+
public float Filed3 { get; set; }
225+
}
226+
227+
public class ModelWithCustomFiledOrder
228+
{
229+
[PrimaryKey]
230+
[AutoIncrement]
231+
[CustomField(Order = 100)]
232+
public int Id { get; set; }
233+
234+
[CustomField(Order = 5)]
235+
public int Filed1 { get; set; }
236+
[CustomField(Order = 13)]
237+
public string Filed2 { get; set; }
238+
[CustomField(Order = 8)]
239+
public float Filed3 { get; set; }
240+
}
163241
}
164242
}

0 commit comments

Comments
 (0)