Skip to content

Commit 9cd36ef

Browse files
committed
2 parents 6779439 + 31e7728 commit 9cd36ef

File tree

16 files changed

+170
-76
lines changed

16 files changed

+170
-76
lines changed

Signum.Engine/Engine/SchemaGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static class SchemaGenerator
2626
Schema s = Schema.Current;
2727
List<ITable> tables = s.GetDatabaseTables().Where(t => !s.IsExternalDatabase(t.Name.Schema.Database)).ToList();
2828

29-
SqlPreCommand? createTables = tables.Select(SqlBuilder.CreateTableSql).Combine(Spacing.Double)?.PlainSqlCommand();
29+
SqlPreCommand? createTables = tables.Select(t => SqlBuilder.CreateTableSql(t)).Combine(Spacing.Double)?.PlainSqlCommand();
3030

3131
SqlPreCommand? foreignKeys = tables.Select(SqlBuilder.AlterTableForeignKeys).Combine(Spacing.Double)?.PlainSqlCommand();
3232

Signum.Engine/Engine/SchemaSynchronizer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ public static class SchemaSynchronizer
210210
removeOld: (tn, dif) => SqlBuilder.DropTable(dif),
211211
mergeBoth: (tn, tab, dif) =>
212212
{
213-
var rename = !object.Equals(dif.Name, tab.Name) ? SqlBuilder.RenameOrMove(dif, tab) : null;
213+
var rename = !object.Equals(dif.Name, tab.Name) ? SqlBuilder.RenameOrMove(dif, tab, tab.Name) : null;
214214

215215
bool disableEnableSystemVersioning = false;
216216

@@ -253,7 +253,7 @@ public static class SchemaSynchronizer
253253

254254
difCol.Name == tabCol.Name ? null : SqlBuilder.RenameColumn(tab.Name, difCol.Name, tabCol.Name),
255255

256-
difCol.ColumnEquals(tabCol, ignorePrimaryKey: true, ignoreIdentity: false, ignoreGenerateAlways: false) ?
256+
difCol.ColumnEquals(tabCol, ignorePrimaryKey: true, ignoreIdentity: false, ignoreGenerateAlways: true) ?
257257
null :
258258
SqlPreCommand.Combine(Spacing.Simple,
259259
tabCol.PrimaryKey && !difCol.PrimaryKey && dif.PrimaryKeyName != null ? SqlBuilder.DropPrimaryKeyConstraint(tab.Name) : null,
@@ -342,7 +342,7 @@ public static class SchemaSynchronizer
342342
SqlPreCommand? historyTables = Synchronizer.SynchronizeScript(Spacing.Double, modelTablesHistory, databaseTablesHistory,
343343
createNew: null,
344344
removeOld: (tn, dif) => SqlBuilder.DropTable(dif.Name),
345-
mergeBoth: (tn, tab, dif) => !object.Equals(dif.Name, tab.SystemVersioned!.TableName) ? SqlBuilder.RenameOrChangeSchema(dif.Name, tab.SystemVersioned!.TableName) : null);
345+
mergeBoth: (tn, tab, dif) => !object.Equals(dif.Name, tab.SystemVersioned!.TableName) ? SqlBuilder.RenameOrMove(dif, tab, tab.SystemVersioned!.TableName) : null);
346346

347347
SqlPreCommand? syncEnums = SynchronizeEnumsScript(replacements);
348348

Signum.Engine/Engine/SqlBuilder.cs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,23 @@ public static class SqlBuilder
2727
};
2828

2929
#region Create Tables
30-
public static SqlPreCommandSimple CreateTableSql(ITable t)
30+
public static SqlPreCommandSimple CreateTableSql(ITable t, ObjectName? tableName = null, bool avoidSystemVersioning = false)
3131
{
32-
var primaryKeyConstraint = t.PrimaryKey == null ? null : "CONSTRAINT {0} PRIMARY KEY CLUSTERED ({1} ASC)".FormatWith(PrimaryClusteredIndex.GetPrimaryKeyName(t.Name), t.PrimaryKey.Name.SqlEscape());
32+
var primaryKeyConstraint = t.PrimaryKey == null || t.SystemVersioned != null && tableName != null && t.SystemVersioned.TableName.Equals(tableName) ?
33+
null : "CONSTRAINT {0} PRIMARY KEY CLUSTERED ({1} ASC)".FormatWith(PrimaryClusteredIndex.GetPrimaryKeyName(t.Name), t.PrimaryKey.Name.SqlEscape());
3334

34-
var systemPeriod = t.SystemVersioned == null ? null : Period(t.SystemVersioned);
35+
var systemPeriod = t.SystemVersioned == null || avoidSystemVersioning ? null : Period(t.SystemVersioned);
3536

36-
var columns = t.Columns.Values.Select(c => SqlBuilder.CreateColumn(c, GetDefaultConstaint(t, c), isChange: false))
37+
var columns = t.Columns.Values.Select(c => SqlBuilder.ColumnLine(c, GetDefaultConstaint(t, c), isChange: false, forHistoryTable: avoidSystemVersioning))
3738
.And(primaryKeyConstraint)
3839
.And(systemPeriod)
3940
.NotNull()
4041
.ToString(",\r\n");
4142

42-
var systemVersioning = t.SystemVersioned == null ? null :
43-
$"\r\nWITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {t.SystemVersioned.TableName}))";
43+
var systemVersioning = t.SystemVersioned == null || avoidSystemVersioning ? null :
44+
$"\r\nWITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {t.SystemVersioned.TableName.OnDatabase(null)}))";
4445

45-
return new SqlPreCommandSimple($"CREATE TABLE {t.Name}(\r\n{columns}\r\n)" + systemVersioning);
46+
return new SqlPreCommandSimple($"CREATE TABLE {tableName ?? t.Name}(\r\n{columns}\r\n)" + systemVersioning);
4647
}
4748

4849
public static SqlPreCommand DropTable(DiffTable diffTable)
@@ -53,7 +54,6 @@ public static SqlPreCommand DropTable(DiffTable diffTable)
5354
return SqlPreCommandConcat.Combine(Spacing.Simple,
5455
AlterTableDisableSystemVersioning(diffTable.Name),
5556
DropTable(diffTable.Name)
56-
//DropTable(diffTable.TemporalTableName)
5757
)!;
5858
}
5959

@@ -95,7 +95,7 @@ public static SqlPreCommand AlterTableDropPeriod(ITable table)
9595

9696
public static SqlPreCommand AlterTableEnableSystemVersioning(ITable table)
9797
{
98-
return new SqlPreCommandSimple($"ALTER TABLE {table.Name} SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {table.SystemVersioned!.TableName}))");
98+
return new SqlPreCommandSimple($"ALTER TABLE {table.Name} SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {table.SystemVersioned!.TableName.OnDatabase(null)}))");
9999
}
100100

101101
public static SqlPreCommandSimple AlterTableDisableSystemVersioning(ObjectName tableName)
@@ -110,7 +110,7 @@ public static SqlPreCommand AlterTableDropColumn(ITable table, string columnName
110110

111111
public static SqlPreCommand AlterTableAddColumn(ITable table, IColumn column, SqlBuilder.DefaultConstraint? tempDefault = null)
112112
{
113-
return new SqlPreCommandSimple("ALTER TABLE {0} ADD {1}".FormatWith(table.Name, CreateColumn(column, tempDefault ?? GetDefaultConstaint(table, column), isChange: false)));
113+
return new SqlPreCommandSimple("ALTER TABLE {0} ADD {1}".FormatWith(table.Name, ColumnLine(column, tempDefault ?? GetDefaultConstaint(table, column), isChange: false)));
114114
}
115115

116116
public static SqlPreCommand AlterTableAddOldColumn(ITable table, DiffColumn column)
@@ -167,7 +167,7 @@ public static bool IsDate(SqlDbType sqlDbType)
167167

168168
public static SqlPreCommand AlterTableAlterColumn(ITable table, IColumn column, string? defaultConstraintName = null, ObjectName? forceTableName = null)
169169
{
170-
var alterColumn = new SqlPreCommandSimple("ALTER TABLE {0} ALTER COLUMN {1}".FormatWith(forceTableName ?? table.Name, CreateColumn(column, null, isChange: true)));
170+
var alterColumn = new SqlPreCommandSimple("ALTER TABLE {0} ALTER COLUMN {1}".FormatWith(forceTableName ?? table.Name, ColumnLine(column, null, isChange: true)));
171171

172172
if (column.Default == null)
173173
return alterColumn;
@@ -224,11 +224,11 @@ public static string CreateOldColumn(DiffColumn c)
224224
);
225225
}
226226

227-
public static string CreateColumn(IColumn c, DefaultConstraint? constraint, bool isChange)
227+
public static string ColumnLine(IColumn c, DefaultConstraint? constraint, bool isChange, bool forHistoryTable = false)
228228
{
229229
string fullType = GetColumnType(c);
230230

231-
var generatedAlways = c is SystemVersionedInfo.Column svc ?
231+
var generatedAlways = c is SystemVersionedInfo.Column svc && !forHistoryTable ?
232232
$"GENERATED ALWAYS AS ROW {(svc.SystemVersionColumnType == SystemVersionedInfo.ColumnType.Start ? "START" : "END")} HIDDEN" :
233233
null;
234234

@@ -237,7 +237,7 @@ public static string CreateColumn(IColumn c, DefaultConstraint? constraint, bool
237237
return $" ".Combine(
238238
c.Name.SqlEscape(),
239239
fullType,
240-
c.Identity && !isChange ? "IDENTITY " : null,
240+
c.Identity && !isChange && !forHistoryTable ? "IDENTITY " : null,
241241
generatedAlways,
242242
c.Collation != null ? ("COLLATE " + c.Collation) : null,
243243
c.Nullable.ToBool() ? "NULL" : "NOT NULL",
@@ -505,18 +505,18 @@ public static SqlPreCommand RenameOrChangeSchema(ObjectName oldTableName, Object
505505
oldNewSchema.Equals(newTableName) ? null : RenameTable(oldNewSchema, newTableName.Name))!;
506506
}
507507

508-
public static SqlPreCommand RenameOrMove(DiffTable oldTable, ITable newTable)
508+
public static SqlPreCommand RenameOrMove(DiffTable oldTable, ITable newTable, ObjectName newTableName)
509509
{
510-
if (object.Equals(oldTable.Name.Schema.Database, newTable.Name.Schema.Database))
511-
return RenameOrChangeSchema(oldTable.Name, newTable.Name);
510+
if (object.Equals(oldTable.Name.Schema.Database, newTableName.Schema.Database))
511+
return RenameOrChangeSchema(oldTable.Name, newTableName);
512512

513513
return SqlPreCommand.Combine(Spacing.Simple,
514-
CreateTableSql(newTable),
515-
MoveRows(oldTable.Name, newTable.Name, newTable.Columns.Keys),
514+
CreateTableSql(newTable, newTableName, avoidSystemVersioning: true),
515+
MoveRows(oldTable.Name, newTableName, newTable.Columns.Keys, avoidIdentityInsert: newTable.SystemVersioned != null && newTable.SystemVersioned.Equals(newTable)),
516516
DropTable(oldTable))!;
517517
}
518518

519-
public static SqlPreCommand MoveRows(ObjectName oldTable, ObjectName newTable, IEnumerable<string> columnNames)
519+
public static SqlPreCommand MoveRows(ObjectName oldTable, ObjectName newTable, IEnumerable<string> columnNames, bool avoidIdentityInsert = false)
520520
{
521521
SqlPreCommandSimple command = new SqlPreCommandSimple(
522522
@"INSERT INTO {0} ({2})
@@ -527,6 +527,9 @@ public static SqlPreCommand MoveRows(ObjectName oldTable, ObjectName newTable, I
527527
columnNames.ToString(a => a.SqlEscape(), ", "),
528528
columnNames.ToString(a => "[table]." + a.SqlEscape(), ", ")));
529529

530+
if (avoidIdentityInsert)
531+
return command;
532+
530533
return SqlPreCommand.Combine(Spacing.Simple,
531534
new SqlPreCommandSimple("SET IDENTITY_INSERT {0} ON".FormatWith(newTable)) { GoBefore = true },
532535
command,

Signum.Engine/Linq/DbExpressions.Sql.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ internal enum SqlFunction
604604
CONVERT,
605605
ISNULL,
606606
STUFF,
607+
COLLATE,
607608
}
608609

609610
internal enum SqlEnums

Signum.Engine/Linq/ExpressionVisitor/DbExpressionNominator.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,8 @@ protected override Expression VisitMember(MemberExpression m)
13161316
return TryLike(m.GetArgument("str"), m.GetArgument("pattern"));
13171317
case "StringExtensions.Etc":
13181318
return TryEtc(m.GetArgument("str"), m.GetArgument("max"), m.TryGetArgument("etcString"));
1319+
case "LinqHints.Collate":
1320+
return TryCollate(m.GetArgument("str"), m.GetArgument("collation"));
13191321

13201322
case "DateTime.Add":
13211323
case "DateTime.Subtract":
@@ -1457,6 +1459,19 @@ protected override Expression VisitMember(MemberExpression m)
14571459
Expression.Call(miEtc3, newStr, max, etcString);
14581460
}
14591461

1462+
private Expression? TryCollate(Expression str, Expression collation)
1463+
{
1464+
var newStr = Visit(str);
1465+
if (!Has(newStr))
1466+
return null;
1467+
1468+
var colStr = collation is ConstantExpression col ? (string)col.Value : null;
1469+
if (colStr == null)
1470+
return null;
1471+
1472+
return Add(new SqlFunctionExpression(typeof(string), newStr, SqlFunction.COLLATE.ToString(), new[] { newStr, new SqlConstantExpression(colStr) }));
1473+
}
1474+
14601475
static readonly MethodInfo miEtc2 = ReflectionTools.GetMethodInfo(() => "".Etc(2));
14611476
static readonly MethodInfo miEtc3 = ReflectionTools.GetMethodInfo(() => "".Etc(2, "..."));
14621477

Signum.Engine/Linq/ExpressionVisitor/QueryFormatter.cs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -535,22 +535,31 @@ protected internal override Expression VisitAggregate(AggregateExpression aggreg
535535

536536
protected internal override Expression VisitSqlFunction(SqlFunctionExpression sqlFunction)
537537
{
538-
if (sqlFunction.Object != null)
538+
if (sqlFunction.SqlFunction == SqlFunction.COLLATE.ToString())
539539
{
540-
Visit(sqlFunction.Object);
541-
sb.Append(".");
540+
this.Visit(sqlFunction.Arguments[0]);
541+
sb.Append(" COLLATE ");
542+
if (sqlFunction.Arguments[1] is SqlConstantExpression ce)
543+
sb.Append((string)ce.Value!);
542544
}
543-
sb.Append(sqlFunction.SqlFunction);
544-
sb.Append("(");
545-
for (int i = 0, n = sqlFunction.Arguments.Count; i < n; i++)
545+
else
546546
{
547-
Expression exp = sqlFunction.Arguments[i];
548-
if (i > 0)
549-
sb.Append(", ");
550-
this.Visit(exp);
547+
if (sqlFunction.Object != null)
548+
{
549+
Visit(sqlFunction.Object);
550+
sb.Append(".");
551+
}
552+
sb.Append(sqlFunction.SqlFunction);
553+
sb.Append("(");
554+
for (int i = 0, n = sqlFunction.Arguments.Count; i < n; i++)
555+
{
556+
Expression exp = sqlFunction.Arguments[i];
557+
if (i > 0)
558+
sb.Append(", ");
559+
this.Visit(exp);
560+
}
561+
sb.Append(")");
551562
}
552-
sb.Append(")");
553-
554563
return sqlFunction;
555564
}
556565

Signum.Engine/Operations/GraphState.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Signum.Engine.Operations
1212
{
13-
public interface IGraphHasFromStatesOperation
13+
public interface IGraphHasStatesOperation
1414
{
1515
bool HasFromStates { get; }
1616
}
@@ -27,7 +27,7 @@ public interface IGraphToStateOperation : IGraphOperation
2727
List<S> ToStates { get; }
2828
}
2929

30-
public interface IGraphFromStatesOperation : IGraphOperation, IGraphHasFromStatesOperation
30+
public interface IGraphFromStatesOperation : IGraphOperation, IGraphHasStatesOperation
3131
{
3232
List<S> FromStates { get; }
3333
}
@@ -186,7 +186,7 @@ public class Execute : Graph<T>.Execute, IGraphToStateOperation, IGraphFromState
186186
IEnumerable<Enum>? IOperation.UntypedFromStates { get { return FromStates.Cast<Enum>(); } }
187187
Type? IOperation.StateType { get { return typeof(S); } }
188188

189-
bool IGraphHasFromStatesOperation.HasFromStates
189+
bool IGraphHasStatesOperation.HasFromStates
190190
{
191191
get { return !FromStates.IsNullOrEmpty(); }
192192
}
@@ -236,7 +236,7 @@ public class Delete : Graph<T>.Delete, IGraphOperation, IGraphFromStatesOperatio
236236
IEnumerable<Enum>? IOperation.UntypedFromStates { get { return FromStates.Cast<Enum>(); } }
237237
Type? IOperation.StateType { get { return typeof(S); } }
238238

239-
bool IGraphHasFromStatesOperation.HasFromStates
239+
bool IGraphHasStatesOperation.HasFromStates
240240
{
241241
get { return !FromStates.IsNullOrEmpty(); }
242242
}

Signum.Engine/Operations/OperationLogic.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ private static OperationInfo ToOperationInfo(IOperation oper)
311311
CanBeModified = (oper as IEntityOperation)?.CanBeModified,
312312
Returns = oper.Returns,
313313
ReturnType = oper.ReturnType,
314-
HasStates = (oper as IGraphHasFromStatesOperation)?.HasFromStates,
314+
HasStates = (oper as IGraphHasStatesOperation)?.HasFromStates,
315315
HasCanExecute = (oper as IEntityOperation)?.HasCanExecute,
316316
CanBeNew = (oper as IEntityOperation)?.CanBeNew,
317317
BaseType = (oper as IEntityOperation)?.BaseType ?? (oper as IConstructorFromManyOperation)?.BaseType

Signum.Entities/Basics/Operation.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,12 @@ public interface IEntityOperationSymbolContainer<in T> : IEntityOperationSymbolC
167167
Type BaseType { get; }
168168
}
169169

170-
public interface IConstructFromManySymbolContainer<in T> : IOperationSymbolContainer
171-
where T : class, IEntity
172-
{
173-
Type BaseType { get; }
174-
}
175-
176170

177171
public static class ConstructSymbol<T>
178172
where T : class, IEntity
179173
{
174+
175+
180176
public interface Simple : IOperationSymbolContainer
181177
{
182178
}
@@ -186,9 +182,10 @@ public interface From<in F> : IEntityOperationSymbolContainer<F>
186182
{
187183
}
188184

189-
public interface FromMany<in F> : IConstructFromManySymbolContainer<F>
185+
public interface FromMany<in F> : IOperationSymbolContainer
190186
where F : class, IEntity
191187
{
188+
Type BaseType { get; }
192189
}
193190
}
194191

Signum.React/Scripts/Frames/FrameModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface PackAndComponent {
4545
lastEntity: string;
4646
refreshCount: number;
4747
getComponent: (ctx: TypeContext<ModifiableEntity>) => React.ReactElement<any>;
48-
}
48+
}
4949

5050
export const FrameModal = React.forwardRef(function FrameModal(p: FrameModalProps, ref: React.Ref<IHandleKeyboard>) {
5151

@@ -188,7 +188,7 @@ export const FrameModal = React.forwardRef(function FrameModal(p: FrameModalProp
188188
function renderBody(pc: PackAndComponent) {
189189

190190
const frame: EntityFrame = {
191-
frameComponent: { forceUpdate },
191+
frameComponent: { forceUpdate, createNew: p.createNew },
192192
entityComponent: entityComponent.current,
193193
onReload: (pack, reloadComponent, callback) => {
194194
const newPack = pack || packComponent!.pack;

Signum.React/Scripts/Lines/ValueLine.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,13 @@ export const ValueLine = React.memo(React.forwardRef(function ValueLine(props: V
164164
return null;
165165

166166
return ValueLineRenderers.renderers[c.props.valueLineType!](c);
167-
}), (prev, next) => LineBaseController.propEquals(prev, next));
167+
}), (prev, next) => {
168+
if (
169+
next.extraButtons || prev.extraButtons)
170+
return false;
171+
172+
return LineBaseController.propEquals(prev, next);
173+
});
168174

169175
export namespace ValueLineRenderers {
170176
export const renderers: {
@@ -176,6 +182,7 @@ export function isNumber(e: React.KeyboardEvent<any>) {
176182
const c = e.keyCode;
177183
return ((c >= 48 && c <= 57) /*0-9*/ ||
178184
(c >= 96 && c <= 105) /*NumPad 0-9*/ ||
185+
(c == KeyCodes.enter) ||
179186
(c == KeyCodes.backspace) ||
180187
(c == KeyCodes.tab) ||
181188
(c == KeyCodes.clear) ||

Signum.React/Scripts/SearchControl/SearchControlLoaded.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,9 @@ export default class SearchControlLoaded extends React.Component<SearchControlLo
174174

175175
canFilter() {
176176
const p = this.props;
177-
return p.showHeader && (p.showFilterButton || p.showFilters)
177+
return p.showHeader == true && (p.showFilterButton || p.showFilters);
178178
}
179179

180-
181180
getQueryRequest(): QueryRequest {
182181
const fo = this.props.findOptions;
183182
const qs = this.props.querySettings;

0 commit comments

Comments
 (0)