diff --git a/src/EventSourcingTests/Internal/Generated/EventStore/EventStorage.cs b/src/EventSourcingTests/Internal/Generated/EventStore/EventStorage.cs index ecc37085b1..43dd6416d8 100644 --- a/src/EventSourcingTests/Internal/Generated/EventStore/EventStorage.cs +++ b/src/EventSourcingTests/Internal/Generated/EventStore/EventStorage.cs @@ -109,6 +109,18 @@ public override async System.Threading.Tasks.Task ApplyReaderDataToEventAsync(Sy e.IsArchived = isArchived; } + + public override Marten.Internal.Operations.IStorageOperation QuickAppendEventWithVersion(Marten.Events.EventGraph events, Marten.Internal.IMartenSession session, Marten.Events.StreamAction stream, Marten.Events.IEvent e) + { + return new Marten.Generated.EventStore.AppendEventOperationQuickWithVersion(stream, e); + } + + + public override Marten.Internal.Operations.IStorageOperation QuickAppendEvents(Marten.Events.StreamAction stream) + { + return new Marten.Generated.EventStore.QuickAppendEventsOperation(stream); + } + } // END: GeneratedEventDocumentStorage @@ -127,30 +139,30 @@ public AppendEventOperation(Marten.Events.StreamAction stream, Marten.Events.IEv } - public const string SQL = "insert into public.mt_events (data, type, mt_dotnet_type, seq_id, id, stream_id, version, timestamp, tenant_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)"; - public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, Marten.Internal.IMartenSession session) { - var parameters = builder.AppendWithParameters(SQL); - parameters[0].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Jsonb; - parameters[0].Value = session.Serializer.ToJson(Event.Data); - parameters[1].Value = Event.EventTypeName != null ? (object)Event.EventTypeName : System.DBNull.Value; - parameters[1].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; - parameters[2].Value = Event.DotNetTypeName != null ? (object)Event.DotNetTypeName : System.DBNull.Value; - parameters[2].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; - parameters[3].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; - parameters[3].Value = Event.Sequence; - parameters[4].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; - parameters[4].Value = Event.Id; - parameters[5].Value = Stream.Id; - parameters[5].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; - parameters[6].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; - parameters[6].Value = Event.Version; - parameters[7].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.TimestampTz; - parameters[7].Value = Event.Timestamp; - parameters[8].Value = Stream.TenantId != null ? (object)Stream.TenantId : System.DBNull.Value; - parameters[8].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + builder.Append("insert into public.mt_events (data, type, mt_dotnet_type, id, stream_id, version, timestamp, tenant_id, seq_id) values ("); + var parameterBuilder = builder.CreateGroupedParameterBuilder(','); + var parameter0 = parameterBuilder.AppendParameter(session.Serializer.ToJson(Event.Data)); + parameter0.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Jsonb; + var parameter1 = Event.EventTypeName != null ? parameterBuilder.AppendParameter(Event.EventTypeName) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + var parameter2 = Event.DotNetTypeName != null ? parameterBuilder.AppendParameter(Event.DotNetTypeName) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + var parameter3 = parameterBuilder.AppendParameter(Event.Id); + parameter3.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; + var parameter4 = parameterBuilder.AppendParameter(Stream.Id); + parameter4.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; + var parameter5 = parameterBuilder.AppendParameter(Event.Version); + parameter5.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; + var parameter6 = parameterBuilder.AppendParameter(Event.Timestamp); + parameter6.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.TimestampTz; + var parameter7 = Stream.TenantId != null ? parameterBuilder.AppendParameter(Stream.TenantId) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter7.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + var parameter8 = parameterBuilder.AppendParameter(Event.Sequence); + parameter8.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; + builder.Append(')'); } } @@ -158,6 +170,75 @@ public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, // END: AppendEventOperation + // START: AppendEventOperationQuickWithVersion + public class AppendEventOperationQuickWithVersion : Marten.Events.Operations.AppendEventOperationBase + { + private readonly Marten.Events.StreamAction _stream; + private readonly Marten.Events.IEvent _e; + + public AppendEventOperationQuickWithVersion(Marten.Events.StreamAction stream, Marten.Events.IEvent e) : base(stream, e) + { + _stream = stream; + _e = e; + } + + + + public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, Marten.Internal.IMartenSession session) + { + builder.Append("insert into public.mt_events (data, type, mt_dotnet_type, id, stream_id, version, timestamp, tenant_id, seq_id) values ("); + var parameterBuilder = builder.CreateGroupedParameterBuilder(','); + var parameter0 = parameterBuilder.AppendParameter(session.Serializer.ToJson(Event.Data)); + parameter0.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Jsonb; + var parameter1 = Event.EventTypeName != null ? parameterBuilder.AppendParameter(Event.EventTypeName) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + var parameter2 = Event.DotNetTypeName != null ? parameterBuilder.AppendParameter(Event.DotNetTypeName) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + var parameter3 = parameterBuilder.AppendParameter(Event.Id); + parameter3.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; + var parameter4 = parameterBuilder.AppendParameter(Stream.Id); + parameter4.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; + var parameter5 = parameterBuilder.AppendParameter(Event.Version); + parameter5.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; + var parameter6 = parameterBuilder.AppendParameter(Event.Timestamp); + parameter6.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.TimestampTz; + var parameter7 = Stream.TenantId != null ? parameterBuilder.AppendParameter(Stream.TenantId) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter7.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + builder.Append(",nextval('public.mt_events_sequence')"); + builder.Append(')'); + } + + } + + // END: AppendEventOperationQuickWithVersion + + + // START: QuickAppendEventsOperation + public class QuickAppendEventsOperation : Marten.Events.Operations.QuickAppendEventsOperationBase + { + private readonly Marten.Events.StreamAction _stream; + + public QuickAppendEventsOperation(Marten.Events.StreamAction stream) : base(stream) + { + _stream = stream; + } + + + + public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, Marten.Internal.IMartenSession session) + { + builder.Append("select public.mt_quick_append_events("); + var parameterBuilder = builder.CreateGroupedParameterBuilder(','); + writeId(parameterBuilder); + writeBasicParameters(parameterBuilder, session); + builder.Append(')'); + } + + } + + // END: QuickAppendEventsOperation + + // START: GeneratedInsertStream public class GeneratedInsertStream : Marten.Events.Operations.InsertStreamBase { @@ -169,20 +250,20 @@ public GeneratedInsertStream(Marten.Events.StreamAction stream) : base(stream) } - public const string SQL = "insert into public.mt_streams (id, type, version, tenant_id) values (?, ?, ?, ?)"; - public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, Marten.Internal.IMartenSession session) { - var parameters = builder.AppendWithParameters(SQL); - parameters[0].Value = Stream.Id; - parameters[0].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; - parameters[1].Value = Stream.AggregateTypeName != null ? (object)Stream.AggregateTypeName : System.DBNull.Value; - parameters[1].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; - parameters[2].Value = Stream.Version; - parameters[2].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; - parameters[3].Value = Stream.TenantId != null ? (object)Stream.TenantId : System.DBNull.Value; - parameters[3].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + builder.Append("insert into public.mt_streams (id, type, version, tenant_id) values ("); + var parameterBuilder = builder.CreateGroupedParameterBuilder(','); + var parameter0 = parameterBuilder.AppendParameter(Stream.Id); + parameter0.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; + var parameter1 = Stream.AggregateTypeName != null ? parameterBuilder.AppendParameter(Stream.AggregateTypeName) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + var parameter2 = parameterBuilder.AppendParameter(Stream.Version); + parameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; + var parameter3 = Stream.TenantId != null ? parameterBuilder.AppendParameter(Stream.TenantId) : parameterBuilder.AppendParameter(System.DBNull.Value); + parameter3.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text; + builder.Append(')'); } } @@ -201,14 +282,12 @@ public GeneratedStreamStateQueryHandler(System.Guid streamId) } - public const string SQL = "select id, version, type, timestamp, created as timestamp, is_archived from public.mt_streams where id = ?"; - public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, Marten.Internal.IMartenSession session) { - var npgsqlParameterArray = builder.AppendWithParameters(SQL); - npgsqlParameterArray[0].Value = _streamId; - npgsqlParameterArray[0].DbType = System.Data.DbType.Guid; + builder.Append("select id, version, type, timestamp, created as timestamp, is_archived from public.mt_streams where id = "); + var parameter1 = builder.AppendParameter(_streamId); + parameter1.DbType = System.Data.DbType.Guid; } @@ -263,18 +342,20 @@ public GeneratedStreamVersionOperation(Marten.Events.StreamAction stream) : base } - public const string SQL = "update public.mt_streams set version = ? where id = ? and version = ?"; - public override void ConfigureCommand(Weasel.Postgresql.ICommandBuilder builder, Marten.Internal.IMartenSession session) { - var parameters = builder.AppendWithParameters(SQL); - parameters[0].Value = Stream.Version; - parameters[0].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; - parameters[1].Value = Stream.Id; - parameters[1].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; - parameters[2].Value = Stream.ExpectedVersionOnServer; - parameters[2].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; + builder.Append("update public.mt_streams "); + var parameterBuilder = builder.CreateGroupedParameterBuilder(); + builder.Append("set version = "); + var parameter0 = parameterBuilder.AppendParameter(Stream.Version); + parameter0.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; + builder.Append("where id = "); + var parameter1 = parameterBuilder.AppendParameter(Stream.Id); + parameter1.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Uuid; + builder.Append("and version = "); + var parameter2 = parameterBuilder.AppendParameter(Stream.ExpectedVersionOnServer); + parameter2.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bigint; } } diff --git a/src/EventSourcingTests/Internal/Generated/EventStore/MyEventProjectionRuntimeSupport2042637388.cs b/src/EventSourcingTests/Internal/Generated/EventStore/MyEventProjectionRuntimeSupport2042637388.cs index 270f576530..85d38d9145 100644 --- a/src/EventSourcingTests/Internal/Generated/EventStore/MyEventProjectionRuntimeSupport2042637388.cs +++ b/src/EventSourcingTests/Internal/Generated/EventStore/MyEventProjectionRuntimeSupport2042637388.cs @@ -23,8 +23,8 @@ public override void ApplyEvent(Marten.IDocumentOperations operations, Marten.Ev { switch (e) { - case Marten.Events.IEvent event_MyEvent11272: - Project1.Invoke(event_MyEvent11272.Data, operations); + case Marten.Events.IEvent event_MyEvent11301: + Project1.Invoke(event_MyEvent11301.Data, operations); break; } diff --git a/src/Marten/Events/CodeGeneration/CodeGenerationExtensions.cs b/src/Marten/Events/CodeGeneration/CodeGenerationExtensions.cs index f393f1ea00..11264c42b9 100644 --- a/src/Marten/Events/CodeGeneration/CodeGenerationExtensions.cs +++ b/src/Marten/Events/CodeGeneration/CodeGenerationExtensions.cs @@ -1,8 +1,11 @@ using System; using System.Linq; using System.Reflection; +using JasperFx.CodeGeneration; +using JasperFx.CodeGeneration.Frames; using JasperFx.Core.Reflection; using Marten.Internal; +using Weasel.Postgresql; namespace Marten.Events.CodeGeneration; @@ -42,4 +45,14 @@ public static Type GetEventType(this MethodInfo method, Type aggregateType) return parameterInfo.ParameterType; } + + public static void AppendSql(this FramesCollection collection, string sql) + { + collection.Code($"{{0}}.{nameof(CommandBuilder.Append)}(\"{sql}\");", Use.Type()); + } + + public static void AppendSql(this FramesCollection collection, char sql) + { + collection.Code($"{{0}}.{nameof(CommandBuilder.Append)}('{sql}');", Use.Type()); + } } diff --git a/src/Marten/Events/CodeGeneration/EventDocumentStorageGenerator.cs b/src/Marten/Events/CodeGeneration/EventDocumentStorageGenerator.cs index 3bb9768114..4279c18099 100644 --- a/src/Marten/Events/CodeGeneration/EventDocumentStorageGenerator.cs +++ b/src/Marten/Events/CodeGeneration/EventDocumentStorageGenerator.cs @@ -109,23 +109,20 @@ private static GeneratedType buildUpdateStreamVersion(GeneratedType builderType, { var operationType = assembly.AddType(UpdateStreamVersionOperationName, typeof(UpdateStreamVersion)); - var sql = $"update {graph.DatabaseSchemaName}.mt_streams set version = ? where id = ? and version = ?"; - if (graph.TenancyStyle == TenancyStyle.Conjoined) - { - sql += $" and {TenantIdColumn.Name} = ?"; - } - - var setter = operationType.AddStringConstant("SQL", sql); + var sql = $"update {graph.DatabaseSchemaName}.mt_streams "; var configureCommand = operationType.MethodFor("ConfigureCommand"); configureCommand.DerivedVariables.Add( new Variable(typeof(StreamAction), nameof(UpdateStreamVersion.Stream))); - configureCommand.Frames.Code($"var parameters = {{0}}.{nameof(CommandBuilder.AppendWithParameters)}(SQL);", - Use.Type()); + configureCommand.Frames.AppendSql(sql); + + configureCommand.Frames.Code($"var parameterBuilder = {{0}}.{nameof(CommandBuilder.CreateGroupedParameterBuilder)}();", Use.Type()); + configureCommand.Frames.AppendSql("set version = "); configureCommand.SetParameterFromMember(0, x => x.Version); + configureCommand.Frames.AppendSql("where id = "); if (graph.StreamIdentity == StreamIdentity.AsGuid) { configureCommand.SetParameterFromMember(1, x => x.Id); @@ -135,10 +132,12 @@ private static GeneratedType buildUpdateStreamVersion(GeneratedType builderType, configureCommand.SetParameterFromMember(1, x => x.Key); } + configureCommand.Frames.AppendSql("and version = "); configureCommand.SetParameterFromMember(2, x => x.ExpectedVersionOnServer); if (graph.TenancyStyle == TenancyStyle.Conjoined) { + configureCommand.Frames.AppendSql($" and {TenantIdColumn.Name} = "); new TenantIdColumn().As().GenerateAppendCode(configureCommand, 3); } @@ -231,31 +230,26 @@ private static GeneratedType buildStreamQueryHandlerType(EventGraph graph, Gener private static void buildConfigureCommandMethodForStreamState(EventGraph graph, GeneratedType streamQueryHandlerType) { - var sql = - $"select id, version, type, timestamp, created as timestamp, is_archived from {graph.DatabaseSchemaName}.mt_streams where id = ?"; if (graph.TenancyStyle == TenancyStyle.Conjoined) { streamQueryHandlerType.AllInjectedFields.Add(new InjectedField(typeof(string), "tenantId")); - sql += $" and {TenantIdColumn.Name} = ?"; } - var setter = streamQueryHandlerType.AddStringConstant("SQL", sql); - var configureCommand = streamQueryHandlerType.MethodFor("ConfigureCommand"); - configureCommand.Frames.Call(x => x.AppendWithParameters(""), call => - { - call.Arguments[0] = setter; - call.ReturnAction = ReturnAction.Initialize; - }); + var sql = + $"select id, version, type, timestamp, created as timestamp, is_archived from {graph.DatabaseSchemaName}.mt_streams where id = "; + + configureCommand.Frames.AppendSql(sql); var idDbType = graph.StreamIdentity == StreamIdentity.AsGuid ? DbType.Guid : DbType.String; - configureCommand.Frames.Code("{0}[0].Value = _streamId;", Use.Type()); - configureCommand.Frames.Code("{0}[0].DbType = {1};", Use.Type(), idDbType); + configureCommand.Frames.Code($"var parameter1 = builder.{nameof(CommandBuilder.AppendParameter)}(_streamId);"); + configureCommand.Frames.Code("parameter1.DbType = {0};", idDbType); if (graph.TenancyStyle == TenancyStyle.Conjoined) { - configureCommand.Frames.Code("{0}[1].Value = _tenantId;", Use.Type()); - configureCommand.Frames.Code("{0}[1].DbType = {1};", Use.Type(), DbType.String); + configureCommand.Frames.AppendSql($" and {TenantIdColumn.Name} = "); + configureCommand.Frames.Code($"var parameter2 = builder.{nameof(CommandBuilder.AppendParameter)}(_tenantId);"); + configureCommand.Frames.Code("parameter2.DbType = {0};", DbType.String); } } @@ -286,18 +280,22 @@ private static GeneratedType buildAppendEventOperation(EventGraph graph, Generat columns.Add(sequence); var sql = - $"insert into {graph.DatabaseSchemaName}.mt_events ({columns.Select(x => x.Name).Join(", ")}) values ({columns.Select(c => c.ValueSql(graph, mode)).Join(", ")})"; + $"insert into {graph.DatabaseSchemaName}.mt_events ({columns.Select(x => x.Name).Join(", ")}) values ("; - operationType.AddStringConstant("SQL", sql); + configure.Frames.AppendSql(sql); - configure.Frames.Code($"var parameters = {{0}}.{nameof(CommandBuilder.AppendWithParameters)}(SQL);", - Use.Type()); + configure.Frames.Code($"var parameterBuilder = {{0}}.{nameof(CommandBuilder.CreateGroupedParameterBuilder)}(',');", Use.Type()); for (var i = 0; i < columns.Count; i++) { columns[i].GenerateAppendCode(configure, graph, i, mode); + var valueSql = columns[i].ValueSql(graph, mode); + if (valueSql != "?") + configure.Frames.AppendSql($"{(i > 0 ? "," : string.Empty)}{valueSql}"); } + configure.Frames.AppendSql(')'); + return operationType; } @@ -306,68 +304,44 @@ private static GeneratedType buildQuickAppendOperation(EventGraph graph, Generat var operationType = assembly.AddType("QuickAppendEventsOperation", typeof(QuickAppendEventsOperationBase)); var table = new EventsTable(graph); - var parameterList = ""; - - var index = 6; - int causationIndex = 0; - int correlationIndex = 0; - int headerIndex = 0; - if (table.Columns.OfType().Any()) - { - parameterList += ", ?"; - causationIndex = ++index; - } - - if (table.Columns.OfType().Any()) - { - parameterList += ", ?"; - correlationIndex = ++index; - } - - if (table.Columns.OfType().Any()) - { - parameterList += ", ?"; - headerIndex = ++index; - } - - var sql = - $"select {graph.DatabaseSchemaName}.mt_quick_append_events(?, ?, ?, ?, ?, ?, ?{parameterList})"; - - operationType.AddStringConstant("SQL", sql); + var sql = $"select {graph.DatabaseSchemaName}.mt_quick_append_events("; var configure = operationType.MethodFor(nameof(QuickAppendEventsOperationBase.ConfigureCommand)); configure.DerivedVariables.Add(new Variable(typeof(StreamAction), nameof(QuickAppendEventsOperationBase.Stream))); - configure.Frames.Code($"var parameters = {{0}}.{nameof(CommandBuilder.AppendWithParameters)}(SQL);", - Use.Type()); + configure.Frames.AppendSql(sql); + + configure.Frames.Code($"var parameterBuilder = {{0}}.{nameof(CommandBuilder.CreateGroupedParameterBuilder)}(',');", Use.Type()); if (graph.StreamIdentity == StreamIdentity.AsGuid) { - configure.Frames.Code("writeId(parameters);"); + configure.Frames.Code("writeId(parameterBuilder);"); } else { - configure.Frames.Code("writeKey(parameters);"); + configure.Frames.Code("writeKey(parameterBuilder);"); } - configure.Frames.Code("writeBasicParameters(parameters, session);"); + configure.Frames.Code("writeBasicParameters(parameterBuilder, session);"); - if (causationIndex > 0) + if (table.Columns.OfType().Any()) { - configure.Frames.Code($"writeCausationIds({causationIndex}, parameters);"); + configure.Frames.Code("writeCausationIds(parameterBuilder);"); } - if (correlationIndex > 0) + if (table.Columns.OfType().Any()) { - configure.Frames.Code($"writeCorrelationIds({correlationIndex}, parameters);"); + configure.Frames.Code("writeCorrelationIds(parameterBuilder);"); } - if (headerIndex > 0) + if (table.Columns.OfType().Any()) { - configure.Frames.Code($"writeHeaders({headerIndex}, parameters, session);"); + configure.Frames.Code("writeHeaders(parameterBuilder, session);"); } + configure.Frames.AppendSql(')'); + return operationType; } @@ -383,20 +357,23 @@ private static GeneratedType buildInsertStream(GeneratedType builderType, Genera .ToArray(); var sql = - $"insert into {graph.DatabaseSchemaName}.mt_streams ({columns.Select(x => x.Name).Join(", ")}) values ({columns.Select(_ => "?").Join(", ")})"; - operationType.AddStringConstant("SQL", sql); + $"insert into {graph.DatabaseSchemaName}.mt_streams ({columns.Select(x => x.Name).Join(", ")}) values ("; + var configureCommand = operationType.MethodFor("ConfigureCommand"); configureCommand.DerivedVariables.Add(new Variable(typeof(StreamAction), nameof(InsertStreamBase.Stream))); - configureCommand.Frames.Code($"var parameters = {{0}}.{nameof(CommandBuilder.AppendWithParameters)}(SQL);", - Use.Type()); + configureCommand.Frames.AppendSql(sql); + + configureCommand.Frames.Code($"var parameterBuilder = {{0}}.{nameof(CommandBuilder.CreateGroupedParameterBuilder)}(',');", Use.Type()); for (var i = 0; i < columns.Length; i++) { columns[i].GenerateAppendCode(configureCommand, i); } + configureCommand.Frames.AppendSql(')'); + builderType.MethodFor(nameof(EventDocumentStorage.InsertStream)) .Frames.ReturnNewGeneratedTypeObject(operationType, "stream"); diff --git a/src/Marten/Events/Daemon/Internals/EventTypeFilter.cs b/src/Marten/Events/Daemon/Internals/EventTypeFilter.cs index 1103f3864e..ec2469dc8e 100644 --- a/src/Marten/Events/Daemon/Internals/EventTypeFilter.cs +++ b/src/Marten/Events/Daemon/Internals/EventTypeFilter.cs @@ -28,9 +28,10 @@ public EventTypeFilter(EventGraph graph, IReadOnlyCollection eventTypes) public void Apply(ICommandBuilder builder) { - var parameters = builder.AppendWithParameters("d.type = ANY(?)"); - parameters[0].NpgsqlDbType = NpgsqlDbType.Varchar | NpgsqlDbType.Array; - parameters[0].Value = _typeNames; + builder.Append("d.type = ANY("); + var parameter = builder.AppendParameter(_typeNames); + parameter.NpgsqlDbType = NpgsqlDbType.Varchar | NpgsqlDbType.Array; + builder.Append(')'); } } diff --git a/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs b/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs index 7cd1128179..195f9bba0b 100644 --- a/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs +++ b/src/Marten/Events/Operations/QuickAppendEventsOperationBase.cs @@ -52,50 +52,55 @@ public void Postprocess(DbDataReader reader, IList exceptions) } } - protected void writeId(NpgsqlParameter[] parameters) + protected void writeId(IGroupedParameterBuilder builder) { - parameters[0].NpgsqlDbType = NpgsqlDbType.Uuid; - parameters[0].Value = Stream.Id; + var param = builder.AppendParameter(Stream.Id); + param.NpgsqlDbType = NpgsqlDbType.Uuid; } - protected void writeKey(NpgsqlParameter[] parameters) + protected void writeKey(IGroupedParameterBuilder builder) { - parameters[0].NpgsqlDbType = NpgsqlDbType.Varchar; - parameters[0].Value = Stream.Key; + var param = builder.AppendParameter(Stream.Key); + param.NpgsqlDbType = NpgsqlDbType.Varchar; } - protected void writeBasicParameters(NpgsqlParameter[] parameters, IMartenSession session) + protected void writeBasicParameters(IGroupedParameterBuilder builder, IMartenSession session) { - parameters[1].NpgsqlDbType = NpgsqlDbType.Varchar; - parameters[1].Value = Stream.AggregateTypeName.IsEmpty() ? DBNull.Value : Stream.AggregateTypeName; - parameters[2].NpgsqlDbType = NpgsqlDbType.Varchar; - parameters[2].Value = Stream.TenantId; - parameters[3].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Uuid; - parameters[3].Value = Stream.Events.Select(x => x.Id).ToArray(); - parameters[4].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; - parameters[4].Value = Stream.Events.Select(x => x.EventTypeName).ToArray(); - parameters[5].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; - parameters[5].Value = Stream.Events.Select(x => x.DotNetTypeName).ToArray(); - parameters[6].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Jsonb; - parameters[6].Value = Stream.Events.Select(e => session.Serializer.ToJson(e.Data)).ToArray(); + var param1 = Stream.AggregateTypeName.IsEmpty() ? builder.AppendParameter(DBNull.Value) : builder.AppendParameter(Stream.AggregateTypeName); + param1.NpgsqlDbType = NpgsqlDbType.Varchar; + + var param2 = builder.AppendParameter(Stream.TenantId); + param2.NpgsqlDbType = NpgsqlDbType.Varchar; + + var param3 = builder.AppendParameter(Stream.Events.Select(x => x.Id).ToArray()); + param3.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Uuid; + + var param4 = builder.AppendParameter(Stream.Events.Select(x => x.EventTypeName).ToArray()); + param4.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; + + var param5 = builder.AppendParameter(Stream.Events.Select(x => x.DotNetTypeName).ToArray()); + param5.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; + + var param6 = builder.AppendParameter(Stream.Events.Select(e => session.Serializer.ToJson(e.Data)).ToArray()); + param6.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Jsonb; } - protected void writeCausationIds(int index, NpgsqlParameter[] parameters) + protected void writeCausationIds(IGroupedParameterBuilder builder) { - parameters[index].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; - parameters[index].Value = Stream.Events.Select(x => x.CausationId).ToArray(); + var param = builder.AppendParameter(Stream.Events.Select(x => x.CausationId).ToArray()); + param.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; } - protected void writeCorrelationIds(int index, NpgsqlParameter[] parameters) + protected void writeCorrelationIds(IGroupedParameterBuilder builder) { - parameters[index].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; - parameters[index].Value = Stream.Events.Select(x => x.CorrelationId).ToArray(); + var param = builder.AppendParameter(Stream.Events.Select(x => x.CorrelationId).ToArray()); + param.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Varchar; } - protected void writeHeaders(int index, NpgsqlParameter[] parameters, IMartenSession session) + protected void writeHeaders(IGroupedParameterBuilder builder, IMartenSession session) { - parameters[index].NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Jsonb; - parameters[index].Value = Stream.Events.Select(x => session.Serializer.ToJson(x.Headers)).ToArray(); + var param = builder.AppendParameter(Stream.Events.Select(x => session.Serializer.ToJson(x.Headers)).ToArray()); + param.NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Jsonb; } public async Task PostprocessAsync(DbDataReader reader, IList exceptions, CancellationToken token) diff --git a/src/Marten/Events/Schema/EventJsonDataColumn.cs b/src/Marten/Events/Schema/EventJsonDataColumn.cs index 2ae77e93e7..ba7fc93830 100644 --- a/src/Marten/Events/Schema/EventJsonDataColumn.cs +++ b/src/Marten/Events/Schema/EventJsonDataColumn.cs @@ -3,6 +3,7 @@ using JasperFx.CodeGeneration.Frames; using Marten.Internal; using NpgsqlTypes; +using Weasel.Postgresql; using Weasel.Postgresql.Tables; namespace Marten.Events.Schema; @@ -26,9 +27,10 @@ public void GenerateSelectorCodeAsync(GeneratedMethod method, EventGraph graph, public void GenerateAppendCode(GeneratedMethod method, EventGraph graph, int index, AppendMode full) { - method.Frames.Code($"parameters[{index}].NpgsqlDbType = {{0}};", NpgsqlDbType.Jsonb); - method.Frames.Code($"parameters[{index}].Value = {{0}}.Serializer.ToJson({{1}}.{nameof(IEvent.Data)});", - Use.Type(), Use.Type()); + method.Frames.Code($"var parameter{index} = parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({{0}}.Serializer.ToJson({{1}}.{nameof(IEvent.Data)}));", + Use.Type(), Use.Type()); + + method.Frames.Code($"parameter{index}.NpgsqlDbType = {{0}};", NpgsqlDbType.Jsonb); } public string ValueSql(EventGraph graph, AppendMode mode) diff --git a/src/Marten/Events/Schema/EventTableColumn.cs b/src/Marten/Events/Schema/EventTableColumn.cs index 4045b1e3c0..b33967949e 100644 --- a/src/Marten/Events/Schema/EventTableColumn.cs +++ b/src/Marten/Events/Schema/EventTableColumn.cs @@ -50,10 +50,11 @@ public void GenerateSelectorCodeAsync(GeneratedMethod method, EventGraph graph, public virtual void GenerateAppendCode(GeneratedMethod method, EventGraph graph, int index, AppendMode full) { - method.Frames.Code($"parameters[{index}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", - NpgsqlDbType); method.Frames.Code( - $"parameters[{index}].{nameof(NpgsqlParameter.Value)} = {{0}}.{Member.Name};", Use.Type()); + $"var parameter{index} = parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({{0}}.{Member.Name});", Use.Type()); + + method.Frames.Code($"parameter{index}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", NpgsqlDbType); + } public virtual string ValueSql(EventGraph graph, AppendMode mode) diff --git a/src/Marten/Internal/CodeGeneration/DocumentFunctionOperationBuilder.cs b/src/Marten/Internal/CodeGeneration/DocumentFunctionOperationBuilder.cs index 5cbcd2771f..99a0849c1f 100644 --- a/src/Marten/Internal/CodeGeneration/DocumentFunctionOperationBuilder.cs +++ b/src/Marten/Internal/CodeGeneration/DocumentFunctionOperationBuilder.cs @@ -8,6 +8,7 @@ using JasperFx.CodeGeneration.Model; using JasperFx.Core; using JasperFx.Core.Reflection; +using Marten.Events.CodeGeneration; using Marten.Internal.Operations; using Marten.Schema; using Marten.Storage; @@ -29,7 +30,7 @@ public DocumentFunctionOperationBuilder(DocumentMapping mapping, UpsertFunction _role = role; _options = options; - CommandText = $"select {_function.Identifier}({_function.OrderedArguments().Select(x => "?").Join(", ")})"; + CommandText = $"select {_function.Identifier}("; ClassName = $"{function.GetType().Name.Replace("Function", "")}{mapping.DocumentType.ToSuffixedTypeName("Operation")}"; @@ -53,7 +54,6 @@ public GeneratedType BuildType(GeneratedAssembly assembly) type.MethodFor("Role").Frames.Return(Constant.ForEnum(_role)); type.MethodFor("DbType").Frames .Return(Constant.ForEnum(PostgresqlProvider.Instance.ToParameterType(_mapping.IdType))); - type.MethodFor("CommandText").Frames.ReturnNewStringConstant("COMMAND_TEXT", CommandText); buildConfigureMethod(type); @@ -154,20 +154,24 @@ private void buildConfigureMethod(GeneratedType type) $"if (document.{_mapping.Metadata.Revision.Member.Name} > 0 && {nameof(IRevisionedOperation.Revision)} == 1) {nameof(IRevisionedOperation.Revision)} = document.{_mapping.Metadata.Revision.Member.Name};"); } - var parameters = method.Arguments[0]; + method.Frames.AppendSql(CommandText); + + var parameterBuilder = method.Arguments[0]; var arguments = _function.OrderedArguments(); for (var i = 0; i < arguments.Length; i++) { var argument = arguments[i]; - argument.GenerateCodeToModifyDocument(method, type, i, parameters, _mapping, _options); + argument.GenerateCodeToModifyDocument(method, type, i, parameterBuilder, _mapping, _options); } for (var i = 0; i < arguments.Length; i++) { var argument = arguments[i]; - argument.GenerateCodeToSetDbParameterValue(method, type, i, parameters, _mapping, _options); + argument.GenerateCodeToSetDbParameterValue(method, type, i, parameterBuilder, _mapping, _options); } + + method.Frames.AppendSql(')'); } } diff --git a/src/Marten/Internal/CodeGeneration/FrameCollectionExtensions.cs b/src/Marten/Internal/CodeGeneration/FrameCollectionExtensions.cs index 14d301f8e2..08b4a19f95 100644 --- a/src/Marten/Internal/CodeGeneration/FrameCollectionExtensions.cs +++ b/src/Marten/Internal/CodeGeneration/FrameCollectionExtensions.cs @@ -9,6 +9,7 @@ using JasperFx.CodeGeneration.Model; using JasperFx.Core; using JasperFx.Core.Reflection; +using Marten.Events.CodeGeneration; using Marten.Linq.Parsing; using Marten.Schema; using Marten.Util; @@ -258,9 +259,8 @@ public static void SetParameterFromMemberNonNullableString(this GeneratedMeth Expression> memberExpression) { var member = MemberFinder.Determine(memberExpression).Single(); - - method.Frames.Code($"parameters[{index}].Value = {{0}}.{member.Name};", Use.Type()); - method.Frames.Code($"parameters[{index}].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text;"); + method.Frames.Code($"var parameter{index} = parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({{1}}.{member.Name});", Use.Type()); + method.Frames.Code($"parameter{index}.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Text;"); } public static void SetParameterFromMember(this GeneratedMethod method, int index, @@ -268,19 +268,20 @@ public static void SetParameterFromMember(this GeneratedMethod method, int in { var member = MemberFinder.Determine(memberExpression).Single(); var memberType = member.GetMemberType(); - var pgType = PostgresqlProvider.Instance.ToParameterType(memberType); + var pgType = PostgresqlProvider.Instance.ToParameterType(memberType!); if (memberType == typeof(string)) { method.Frames.Code( - $"parameters[{index}].Value = {{0}}.{member.Name} != null ? (object){{0}}.{member.Name} : {typeof(DBNull).FullNameInCode()}.Value;", + $"var parameter{index} = {{0}}.{member.Name} != null ? parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({{0}}.{member.Name}) : parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({typeof(DBNull).FullNameInCode()}.Value);", Use.Type()); - method.Frames.Code($"parameters[{index}].NpgsqlDbType = {{0}};", pgType); + method.Frames.Code($"parameter{index}.NpgsqlDbType = {{0}};", pgType); } else { - method.Frames.Code($"parameters[{index}].Value = {{0}}.{member.Name};", Use.Type()); - method.Frames.Code($"parameters[{index}].NpgsqlDbType = {{0}};", pgType); + method.Frames.Code($"var parameter{index} = parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({{0}}.{member.Name});", Use.Type()); + method.Frames.Code($"parameter{index}.NpgsqlDbType = {{0}};", pgType); + } } diff --git a/src/Marten/Internal/CompiledQueries/CompiledQueryPlan.cs b/src/Marten/Internal/CompiledQueries/CompiledQueryPlan.cs index 2ed3210fa7..ac55385054 100644 --- a/src/Marten/Internal/CompiledQueries/CompiledQueryPlan.cs +++ b/src/Marten/Internal/CompiledQueries/CompiledQueryPlan.cs @@ -145,6 +145,20 @@ NpgsqlParameter ICommandBuilder.AppendParameter(T value) return usage.Parameter; } + public NpgsqlParameter AppendParameter(T value, NpgsqlDbType dbType) + { + _current ??= appendCommand(); + var name = "p" + _parameterIndex; + _parameterIndex++; + var usage = new ParameterUsage(_current.Parameters.Count, name, value, dbType); + _current.Parameters.Add(usage); + + _current.CommandText += ParameterPlaceholder; + + return usage.Parameter; + } + + private int _parameterIndex = 0; NpgsqlParameter ICommandBuilder.AppendParameter(object value) @@ -184,6 +198,11 @@ void ICommandBuilder.AppendParameters(params object[] parameters) throw new NotSupportedException(); } + public IGroupedParameterBuilder CreateGroupedParameterBuilder(char? seperator = null) + { + throw new NotSupportedException(); + } + NpgsqlParameter[] ICommandBuilder.AppendWithParameters(string text) { _current ??= appendCommand(); diff --git a/src/Marten/Internal/Operations/StorageOperation.cs b/src/Marten/Internal/Operations/StorageOperation.cs index 35f3776534..5921a2c64e 100644 --- a/src/Marten/Internal/Operations/StorageOperation.cs +++ b/src/Marten/Internal/Operations/StorageOperation.cs @@ -55,8 +55,9 @@ public IChangeTracker ToTracker(IMartenSession session) public void ConfigureCommand(ICommandBuilder builder, IMartenSession session) { - var parameters = builder.AppendWithParameters(CommandText()); - ConfigureParameters(parameters, _document, session); + var groupedParameters = builder.CreateGroupedParameterBuilder(','); + // this is gross + ConfigureParameters(groupedParameters, builder, _document, session); } public Type DocumentType => typeof(T); @@ -73,16 +74,14 @@ public virtual Task PostprocessAsync(DbDataReader reader, IList excep public abstract OperationRole Role(); - public abstract string CommandText(); - public abstract NpgsqlDbType DbType(); - public abstract void ConfigureParameters(NpgsqlParameter[] parameters, T document, IMartenSession session); + public abstract void ConfigureParameters(IGroupedParameterBuilder parameterBuilder, ICommandBuilder builder, T document, IMartenSession session); - protected void setVersionParameter(NpgsqlParameter parameter) + protected void setVersionParameter(IGroupedParameterBuilder builder) { + var parameter = builder.AppendParameter(_version); parameter.NpgsqlDbType = NpgsqlDbType.Uuid; - parameter.Value = _version; } protected void storeVersion() @@ -90,23 +89,24 @@ protected void storeVersion() _versions[_id] = _version; } - protected void setCurrentVersionParameter(NpgsqlParameter parameter) + protected void setCurrentVersionParameter(IGroupedParameterBuilder builder) { - parameter.NpgsqlDbType = NpgsqlDbType.Uuid; if (_versions.TryGetValue(_id, out var version)) { - parameter.Value = version; + var parameter = builder.AppendParameter(version); + parameter.NpgsqlDbType = NpgsqlDbType.Uuid; } else { - parameter.Value = DBNull.Value; + var parameter = builder.AppendParameter(DBNull.Value); + parameter.NpgsqlDbType = NpgsqlDbType.Uuid; } } - protected void setCurrentRevisionParameter(NpgsqlParameter parameter) + protected void setCurrentRevisionParameter(IGroupedParameterBuilder builder) { + var parameter = builder.AppendParameter(Revision); parameter.NpgsqlDbType = NpgsqlDbType.Integer; - parameter.Value = Revision; } protected bool postprocessConcurrency(DbDataReader reader, IList exceptions) @@ -254,29 +254,31 @@ public bool TryTransform(Exception original, out Exception transformed) return false; } - protected void setStringParameter(NpgsqlParameter parameter, string value) + protected void setStringParameter(IGroupedParameterBuilder builder, string value) { - parameter.NpgsqlDbType = NpgsqlDbType.Varchar; if (value == null) { - parameter.Value = DBNull.Value; + var parameter = builder.AppendParameter(DBNull.Value); + parameter.NpgsqlDbType = NpgsqlDbType.Varchar; } else { - parameter.Value = value; + var parameter = builder.AppendParameter(value); + parameter.NpgsqlDbType = NpgsqlDbType.Varchar; } } - protected void setHeaderParameter(NpgsqlParameter parameter, IMartenSession session) + protected void setHeaderParameter(IGroupedParameterBuilder builder, IMartenSession session) { - parameter.NpgsqlDbType = NpgsqlDbType.Jsonb; if (session.Headers == null) { - parameter.Value = DBNull.Value; + var parameter = builder.AppendParameter(DBNull.Value); + parameter.NpgsqlDbType = NpgsqlDbType.Jsonb; } else { - parameter.Value = session.Serializer.ToJson(session.Headers); + var parameter = builder.AppendParameter(session.Serializer.ToJson(session.Headers)); + parameter.NpgsqlDbType = NpgsqlDbType.Jsonb; } } } diff --git a/src/Marten/LinqExtensions.cs b/src/Marten/LinqExtensions.cs index c8444d2a9b..e566146fb7 100644 --- a/src/Marten/LinqExtensions.cs +++ b/src/Marten/LinqExtensions.cs @@ -1,6 +1,7 @@ #nullable enable using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using JasperFx.Core.Reflection; using Marten.Schema; @@ -127,7 +128,7 @@ public static bool IsSupersetOf(this IEnumerable enumerable, IEnumerable /// /// - public static bool IsEmpty(this IEnumerable? enumerable) + public static bool IsEmpty([NotNullWhen(false)] this IEnumerable? enumerable) { if (enumerable == null) { diff --git a/src/Marten/Schema/Arguments/CurrentVersionArgument.cs b/src/Marten/Schema/Arguments/CurrentVersionArgument.cs index a71ce55e9a..eda858d887 100644 --- a/src/Marten/Schema/Arguments/CurrentVersionArgument.cs +++ b/src/Marten/Schema/Arguments/CurrentVersionArgument.cs @@ -1,6 +1,8 @@ using JasperFx.CodeGeneration; +using JasperFx.CodeGeneration.Frames; using JasperFx.CodeGeneration.Model; using NpgsqlTypes; +using Weasel.Postgresql; namespace Marten.Schema.Arguments; @@ -18,6 +20,6 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code("setCurrentVersionParameter({0}[{1}]);", parameters, i); + method.Frames.Code("setCurrentVersionParameter({0});", Use.Type()); } } diff --git a/src/Marten/Schema/Arguments/DocJsonBodyArgument.cs b/src/Marten/Schema/Arguments/DocJsonBodyArgument.cs index 8a9085c04b..098b5da45d 100644 --- a/src/Marten/Schema/Arguments/DocJsonBodyArgument.cs +++ b/src/Marten/Schema/Arguments/DocJsonBodyArgument.cs @@ -4,6 +4,7 @@ using JasperFx.CodeGeneration.Model; using Marten.Internal; using NpgsqlTypes; +using Weasel.Postgresql; namespace Marten.Schema.Arguments; @@ -36,8 +37,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code($"{parameters.Usage}[{i}].NpgsqlDbType = {{0}};", NpgsqlDbType.Jsonb); - method.Frames.Code($"{parameters.Usage}[{i}].Value = {{0}}.Serializer.ToJson(_document);", - Use.Type()); + method.Frames.Code($"var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}({{1}}.Serializer.ToJson(_document));", Use.Type(), Use.Type()); + method.Frames.Code($"parameter{i}.NpgsqlDbType = {{0}};", NpgsqlDbType.Jsonb); } } diff --git a/src/Marten/Schema/Arguments/DocTypeArgument.cs b/src/Marten/Schema/Arguments/DocTypeArgument.cs index aa75bfc961..9700996473 100644 --- a/src/Marten/Schema/Arguments/DocTypeArgument.cs +++ b/src/Marten/Schema/Arguments/DocTypeArgument.cs @@ -4,9 +4,11 @@ using JasperFx.CodeGeneration.Frames; using JasperFx.CodeGeneration.Model; using JasperFx.Core.Reflection; +using Marten.Events.CodeGeneration; using Marten.Internal.CodeGeneration; using Npgsql; using NpgsqlTypes; +using Weasel.Postgresql; namespace Marten.Schema.Arguments; @@ -39,8 +41,8 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", DbType); - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = docType;"); + method.Frames.Code($"var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}(docType);", Use.Type()); + method.Frames.Code($"parameter{i}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", DbType); } public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) diff --git a/src/Marten/Schema/Arguments/DotNetTypeArgument.cs b/src/Marten/Schema/Arguments/DotNetTypeArgument.cs index 20eb0bd6c5..041cb2e5e5 100644 --- a/src/Marten/Schema/Arguments/DotNetTypeArgument.cs +++ b/src/Marten/Schema/Arguments/DotNetTypeArgument.cs @@ -6,6 +6,7 @@ using JasperFx.CodeGeneration.Model; using JasperFx.Core.Reflection; using NpgsqlTypes; +using Weasel.Postgresql; namespace Marten.Schema.Arguments; @@ -32,8 +33,8 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G var version = type.AllInjectedFields[0]; method.Frames.Code("// .Net Class Type"); - method.Frames.Code("{0}[{1}].NpgsqlDbType = {2};", parameters, i, DbType); - method.Frames.Code("{0}[{1}].Value = {2}.GetType().FullName;", parameters, i, version); + method.Frames.Code($"var parameter{{0}} = {{1}}.{nameof(IGroupedParameterBuilder.AppendParameter)}({{2}}.GetType().FullName);", i, Use.Type(), version); + method.Frames.Code("parameter{0}.NpgsqlDbType = {1};", i, DbType); } public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) diff --git a/src/Marten/Schema/Arguments/RevisionArgument.cs b/src/Marten/Schema/Arguments/RevisionArgument.cs index e1f61676ef..7bece46807 100644 --- a/src/Marten/Schema/Arguments/RevisionArgument.cs +++ b/src/Marten/Schema/Arguments/RevisionArgument.cs @@ -20,7 +20,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code("setCurrentRevisionParameter({0}[{1}]);", parameters, i); + method.Frames.Code("setCurrentRevisionParameter(parameterBuilder);"); } public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) diff --git a/src/Marten/Schema/Arguments/TenantIdArgument.cs b/src/Marten/Schema/Arguments/TenantIdArgument.cs index 40bec372b3..a0e7811ef6 100644 --- a/src/Marten/Schema/Arguments/TenantIdArgument.cs +++ b/src/Marten/Schema/Arguments/TenantIdArgument.cs @@ -5,6 +5,7 @@ using Marten.Internal.CodeGeneration; using Marten.Storage.Metadata; using NpgsqlTypes; +using Weasel.Postgresql; namespace Marten.Schema.Arguments; @@ -37,8 +38,8 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code("{0}[{1}].Value = _tenantId;", parameters, i); - method.Frames.Code("{0}[{1}].NpgsqlDbType = {2};", parameters, i, DbType); + method.Frames.Code($"var parameter{{0}} = parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}(_tenantId);", i); + method.Frames.Code("parameter{0}.NpgsqlDbType = {1};", i, DbType); } public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) diff --git a/src/Marten/Schema/Arguments/UpsertArgument.cs b/src/Marten/Schema/Arguments/UpsertArgument.cs index 150469fd18..b469e078f4 100644 --- a/src/Marten/Schema/Arguments/UpsertArgument.cs +++ b/src/Marten/Schema/Arguments/UpsertArgument.cs @@ -117,22 +117,21 @@ public virtual void GenerateCodeToSetDbParameterValue(GeneratedMethod method, Ge ? $"{Constant.ForEnum(NpgsqlDbType.Array).Usage} | {Constant.ForEnum(PostgresqlProvider.Instance.ToParameterType(rawMemberType.GetElementType())).Usage}" : Constant.ForEnum(DbType).Usage; - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {dbTypeString};"); - if (rawMemberType.IsClass || rawMemberType.IsNullable() || _members.Length > 1) { method.Frames.Code($@" BLOCK:if (document.{memberPath} != null) -{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = document.{ParameterValue}; +var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}(document.{ParameterValue}); +parameter{i}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {dbTypeString}; END BLOCK:else -{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = {typeof(DBNull).FullNameInCode()}.{nameof(DBNull.Value)}; +var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}({typeof(DBNull).FullNameInCode()}.Value); END -"); +", Use.Type()); } else { - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = document.{ParameterValue};"); + method.Frames.Code($"var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}(document.{ParameterValue});", Use.Type()); } } } @@ -144,32 +143,33 @@ private void writeEnumerationValues(GeneratedMethod method, int i, Argument para { if (DotNetType.IsNullable()) { - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", - NpgsqlDbType.Integer); method.Frames.Code( - $"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = document.{memberPath} == null ? (object){typeof(DBNull).FullNameInCode()}.Value : (object)((int)document.{memberPath});"); + $"var parameter{i} = document.{memberPath} == null ? {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}({typeof(DBNull).FullNameInCode()}.Value) : {{0}}.{nameof(CommandBuilder.AppendParameter)}((int)document.{memberPath});", + Use.Type()); + + method.Frames.Code($"parameter{i}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", NpgsqlDbType.Integer); } else { - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", - NpgsqlDbType.Integer); method.Frames.Code( - $"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = (int)document.{memberPath};"); + $"var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}((int)document.{memberPath});", Use.Type()); + method.Frames.Code($"parameter{i}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", + NpgsqlDbType.Integer); } } else if (DotNetType.IsNullable()) { - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", - NpgsqlDbType.Varchar); method.Frames.Code( - $"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = (document.{memberPath} ).ToString();"); + $"var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}((document.{memberPath}).ToString());", Use.Type()); + method.Frames.Code($"parameter{i}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", + NpgsqlDbType.Varchar); } else { - method.Frames.Code($"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", - NpgsqlDbType.Varchar); method.Frames.Code( - $"{parameters.Usage}[{i}].{nameof(NpgsqlParameter.Value)} = document.{memberPath}.ToString();"); + $"var parameter{i} = {{0}}.{nameof(IGroupedParameterBuilder.AppendParameter)}(document.{memberPath}.ToString());", Use.Type()); + method.Frames.Code($"parameter{i}.{nameof(NpgsqlParameter.NpgsqlDbType)} = {{0}};", + NpgsqlDbType.Varchar); } } diff --git a/src/Marten/Schema/Arguments/VersionArgument.cs b/src/Marten/Schema/Arguments/VersionArgument.cs index 7f3742b4a2..247c73c4b8 100644 --- a/src/Marten/Schema/Arguments/VersionArgument.cs +++ b/src/Marten/Schema/Arguments/VersionArgument.cs @@ -43,7 +43,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code("setVersionParameter({0}[{1}]);", parameters, i); + method.Frames.Code("setVersionParameter(parameterBuilder);"); } public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) diff --git a/src/Marten/Storage/Metadata/CausationIdColumn.cs b/src/Marten/Storage/Metadata/CausationIdColumn.cs index 08b1e371ca..ee0c7ef5af 100644 --- a/src/Marten/Storage/Metadata/CausationIdColumn.cs +++ b/src/Marten/Storage/Metadata/CausationIdColumn.cs @@ -102,7 +102,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code($"setStringParameter({parameters.Usage}[{i}], {{0}}.{nameof(IMartenSession.CausationId)});", + method.Frames.Code($"setStringParameter({parameters.Usage}, {{0}}.{nameof(IMartenSession.CausationId)});", Use.Type()); } diff --git a/src/Marten/Storage/Metadata/CorrelationIdColumn.cs b/src/Marten/Storage/Metadata/CorrelationIdColumn.cs index 2666a4c863..927d4c6619 100644 --- a/src/Marten/Storage/Metadata/CorrelationIdColumn.cs +++ b/src/Marten/Storage/Metadata/CorrelationIdColumn.cs @@ -104,7 +104,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G DocumentMapping mapping, StoreOptions options) { method.Frames.Code( - $"setStringParameter({parameters.Usage}[{i}], {{0}}.{nameof(IMartenSession.CorrelationId)});", + $"setStringParameter({parameters.Usage} {{0}}.{nameof(IMartenSession.CorrelationId)});", Use.Type()); } diff --git a/src/Marten/Storage/Metadata/HeadersColumn.cs b/src/Marten/Storage/Metadata/HeadersColumn.cs index 78ab6ab72e..176bf01a4e 100644 --- a/src/Marten/Storage/Metadata/HeadersColumn.cs +++ b/src/Marten/Storage/Metadata/HeadersColumn.cs @@ -14,6 +14,7 @@ using Marten.Schema; using Marten.Schema.Arguments; using NpgsqlTypes; +using Weasel.Postgresql; namespace Marten.Storage.Metadata; @@ -45,9 +46,8 @@ public void GenerateSelectorCodeAsync(GeneratedMethod method, EventGraph graph, public void GenerateAppendCode(GeneratedMethod method, EventGraph graph, int index, AppendMode full) { - method.Frames.Code($"parameters[{index}].NpgsqlDbType = {{0}};", NpgsqlDbType.Jsonb); - method.Frames.Code($"parameters[{index}].Value = {{0}}.Serializer.ToJson({{1}}.{nameof(IEvent.Headers)});", - Use.Type(), Use.Type()); + method.Frames.Code($"var parameter{index} = parameterBuilder.{nameof(IGroupedParameterBuilder.AppendParameter)}({{0}}.Serializer.ToJson({{1}}.{nameof(IEvent.Headers)}));", Use.Type(), Use.Type()); + method.Frames.Code($"parameter{index}.NpgsqlDbType = {{0}};", NpgsqlDbType.Jsonb); } internal override async Task ApplyAsync(IMartenSession martenSession, DocumentMetadata metadata, int index, @@ -116,7 +116,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G Argument parameters, DocumentMapping mapping, StoreOptions options) { - method.Frames.Code($"setHeaderParameter({parameters.Usage}[{i}], {{0}});", Use.Type()); + method.Frames.Code($"setHeaderParameter({parameters.Usage}, {{0}});", Use.Type()); } public override void GenerateBulkWriterCode(GeneratedType type, GeneratedMethod load, DocumentMapping mapping) diff --git a/src/Marten/Storage/Metadata/LastModifiedByColumn.cs b/src/Marten/Storage/Metadata/LastModifiedByColumn.cs index 7e80420332..11f44170be 100644 --- a/src/Marten/Storage/Metadata/LastModifiedByColumn.cs +++ b/src/Marten/Storage/Metadata/LastModifiedByColumn.cs @@ -75,7 +75,7 @@ public override void GenerateCodeToSetDbParameterValue(GeneratedMethod method, G DocumentMapping mapping, StoreOptions options) { method.Frames.Code( - $"setStringParameter({parameters.Usage}[{i}], {{0}}.{nameof(IMartenSession.LastModifiedBy)});", + $"setStringParameter({parameters.Usage} {{0}}.{nameof(IMartenSession.LastModifiedBy)});", Use.Type()); }