@@ -56,11 +56,11 @@ public void FlushUpdates()
5656 }
5757
5858 var groupedUpdates = updateBuffer
59- . GroupBy ( update => update . Table )
60- . ToDictionary (
61- group => group . Key ,
62- group => group . Select ( update => new TableUpdateOperation ( update . OpType , update . RowId ) ) . ToArray ( )
63- ) ;
59+ . GroupBy ( update => update . Table )
60+ . ToDictionary (
61+ group => group . Key ,
62+ group => group . Select ( update => new TableUpdateOperation ( update . OpType , update . RowId ) ) . ToArray ( )
63+ ) ;
6464
6565 var batchedUpdate = new BatchedUpdateNotification
6666 {
@@ -81,19 +81,15 @@ private static List<string> PrepareQueryString(ref string query, int parameterCo
8181 return parameterList ;
8282 }
8383
84- int placeholderCount = query . Count ( c => c == '?' ) ;
85- if ( placeholderCount != parameterCount )
86- {
87- throw new ArgumentException ( $ "Number of parameters ({ parameterCount } ) does not match the number of `?` placeholders ({ placeholderCount } ) in the query.") ;
88- }
89-
9084 // Replace `?` sequentially with named parameters
91- var sb = new StringBuilder ( ) ;
85+ var sb = new StringBuilder ( query . Length + parameterCount * 7 ) ;
9286 int lastPos = 0 ;
9387 int currentPos ;
9488 for ( int i = 0 ; i < parameterCount ; i ++ )
9589 {
9690 currentPos = query . IndexOf ( '?' , lastPos ) ;
91+ if ( currentPos == - 1 )
92+ throw new ArgumentException ( $ "Not enough `?` placeholders for { parameterCount } parameters.") ;
9793
9894 string paramName = $ "@param{ i } ";
9995 parameterList . Add ( paramName ) ;
@@ -115,7 +111,7 @@ private static List<string> PrepareQueryString(ref string query, int parameterCo
115111 return parameterList ;
116112 }
117113
118- private static DynamicParameters ? PrepareQuery ( ref string query , object ? [ ] ? parameters )
114+ private static Dictionary < string , object ? > ? PrepareQuery ( ref string query , object ? [ ] ? parameters )
119115 {
120116 if ( parameters == null || parameters . Length == 0 )
121117 {
@@ -125,121 +121,128 @@ private static List<string> PrepareQueryString(ref string query, int parameterCo
125121 int parameterCount = parameters . Length ;
126122 var parameterNames = PrepareQueryString ( ref query , parameterCount ) ;
127123
128- var dynamicParams = new DynamicParameters ( ) ;
124+ var paramDict = new Dictionary < string , object ? > ( parameterCount ) ;
129125
130126 for ( int i = 0 ; i < parameterCount ; i ++ )
131127 {
132- dynamicParams . Add ( parameterNames [ i ] , parameters [ i ] ) ;
128+ paramDict [ parameterNames [ i ] ] = parameters [ i ] ;
133129 }
134130
135- return dynamicParams ;
136- }
137-
138- private static List < DynamicParameters > ? PrepareQuery ( ref string query , object ? [ ] [ ] ? parameters )
139- {
140- if ( parameters == null || parameters . Length == 0 )
141- {
142- return null ;
143- }
144-
145- var parameterCount = parameters [ 0 ] . Length ;
146- if ( parameterCount == 0 )
147- {
148- return null ;
149- }
150-
151- var parameterNames = PrepareQueryString ( ref query , parameterCount ) ;
152-
153- var dynamicParamsList = new List < DynamicParameters > ( ) ;
154-
155- foreach ( var paramSet in parameters )
156- {
157- if ( paramSet . Length != parameterCount )
158- {
159- throw new ArgumentException ( "Parameter sets have different number of arguments." ) ;
160- }
161-
162- var dynamicParams = new DynamicParameters ( ) ;
163- for ( int i = 0 ; i < parameterCount ; i ++ )
164- {
165- dynamicParams . Add ( parameterNames [ i ] , paramSet [ i ] ) ;
166- }
167- dynamicParamsList . Add ( dynamicParams ) ;
168- }
169-
170- return dynamicParamsList ;
131+ return paramDict ;
171132 }
172133
173134 public Task < T [ ] > GetAll < T > ( string query , object ? [ ] ? parameters = null )
174135 {
175- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
136+ var dynamicParams = PrepareQuery ( ref query , parameters ) ;
176137 return Task . Run ( async ( ) => ( await Db . QueryAsync < T > ( query , dynamicParams , commandType : CommandType . Text ) ) . ToArray ( ) ) ;
177138 }
178139
179140 public Task < dynamic [ ] > GetAll ( string query , object ? [ ] ? parameters = null )
180141 {
181- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
142+ var dynamicParams = PrepareQuery ( ref query , parameters ) ;
182143 return Task . Run ( async ( ) => ( await Db . QueryAsync ( query , dynamicParams , commandType : CommandType . Text ) ) . ToArray ( ) ) ;
183144 }
184145
185146 public Task < T ? > GetOptional < T > ( string query , object ? [ ] ? parameters = null )
186147 {
187- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
148+ var dynamicParams = PrepareQuery ( ref query , parameters ) ;
188149 return Task . Run ( ( ) => Db . QueryFirstOrDefaultAsync < T > ( query , dynamicParams , commandType : CommandType . Text ) ) ;
189150 }
190151
191152 public Task < dynamic ? > GetOptional ( string query , object ? [ ] ? parameters = null )
192153 {
193- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
154+ var dynamicParams = PrepareQuery ( ref query , parameters ) ;
194155 return Task . Run ( ( ) => Db . QueryFirstOrDefaultAsync ( query , dynamicParams , commandType : CommandType . Text ) ) ;
195156 }
196157
197158 public Task < T > Get < T > ( string query , object ? [ ] ? parameters = null )
198159 {
199- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
160+ var dynamicParams = PrepareQuery ( ref query , parameters ) ;
200161 return Task . Run ( ( ) => Db . QueryFirstAsync < T > ( query , dynamicParams , commandType : CommandType . Text ) ) ;
201162 }
202163
203164 public Task < dynamic > Get ( string query , object ? [ ] ? parameters = null )
204165 {
205- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
166+ var dynamicParams = PrepareQuery ( ref query , parameters ) ;
206167 return Task . Run ( ( ) => Db . QueryFirstAsync ( query , dynamicParams , commandType : CommandType . Text ) ) ;
207168 }
208169
209- public Task < NonQueryResult > Execute ( string query , object ? [ ] ? parameters = null )
170+ private static void PrepareCommandParameters ( SqliteCommand command , ref string query , int parameterCount )
210171 {
211- DynamicParameters ? dynamicParams = PrepareQuery ( ref query , parameters ) ;
212- return Task . Run ( async ( ) =>
172+ var parameterNames = PrepareQueryString ( ref query , parameterCount ) ;
173+ command . CommandText = query ;
174+ foreach ( var paramName in parameterNames )
213175 {
214- int rowsAffected = await Db . ExecuteAsync ( query , dynamicParams , commandType : CommandType . Text ) ;
215- return new NonQueryResult
176+ var parameter = command . CreateParameter ( ) ;
177+ parameter . ParameterName = paramName ;
178+ command . Parameters . Add ( parameter ) ;
179+ }
180+ }
181+
182+ private static void PrepareCommand ( SqliteCommand command , ref string query , object ? [ ] ? parameters )
183+ {
184+ int parameterCount = parameters ? . Length ?? 0 ;
185+ PrepareCommandParameters ( command , ref query , parameterCount ) ;
186+
187+ if ( parameters != null )
188+ {
189+ for ( int i = 0 ; i < parameters . Length ; i ++ )
216190 {
217- InsertId = raw . sqlite3_last_insert_rowid ( Db . Handle ) ,
218- RowsAffected = rowsAffected ,
219- } ;
220- } ) ;
191+ command . Parameters [ i ] . Value = parameters [ i ] ?? DBNull . Value ;
192+ }
193+ }
221194 }
222195
196+ public Task < NonQueryResult > Execute ( string query , object ? [ ] ? parameters = null ) => Task . Run ( ( ) =>
197+ {
198+ using var command = Db . CreateCommand ( ) ;
199+ PrepareCommand ( command , ref query , parameters ) ;
200+
201+ int rowsAffected = command . ExecuteNonQuery ( ) ;
202+ return new NonQueryResult
203+ {
204+ InsertId = raw . sqlite3_last_insert_rowid ( Db . Handle ) ,
205+ RowsAffected = rowsAffected ,
206+ } ;
207+ } ) ;
208+
223209 public Task < NonQueryResult > ExecuteBatch ( string query , object ? [ ] [ ] ? parameters = null )
224210 {
225211 if ( parameters == null || parameters . Length == 0 )
226212 {
227213 return Task . FromResult ( new NonQueryResult { RowsAffected = 0 } ) ;
228214 }
229215
230- List < DynamicParameters > ? dynamicParamsList = PrepareQuery ( ref query , parameters ) ;
231- if ( dynamicParamsList == null )
216+ int parameterCount = parameters [ 0 ] . Length ;
217+ if ( parameterCount == 0 )
232218 {
233219 return Task . FromResult ( new NonQueryResult { RowsAffected = 0 } ) ;
234220 }
235221
236- return Task . Run ( async ( ) =>
222+ return Task . Run ( ( ) =>
237223 {
238- int rowsAffected = await Db . ExecuteAsync ( query , dynamicParamsList , commandType : CommandType . Text ) ;
224+ int totalRowsAffected = 0 ;
225+
226+ using var command = Db . CreateCommand ( ) ;
227+ PrepareCommandParameters ( command , ref query , parameterCount ) ;
228+
229+ foreach ( var paramSet in parameters )
230+ {
231+ if ( paramSet != null )
232+ {
233+ for ( int i = 0 ; i < paramSet . Length ; i ++ )
234+ {
235+ command . Parameters [ i ] . Value = paramSet [ i ] ?? DBNull . Value ;
236+ }
237+ }
238+
239+ totalRowsAffected += command . ExecuteNonQuery ( ) ;
240+ }
241+
239242 return new NonQueryResult
240243 {
241244 InsertId = raw . sqlite3_last_insert_rowid ( Db . Handle ) ,
242- RowsAffected = rowsAffected ,
245+ RowsAffected = totalRowsAffected ,
243246 } ;
244247 } ) ;
245248 }
0 commit comments