@@ -177,6 +177,88 @@ void installSequel(jsi::Runtime &rt, const char *docPath)
177177 return move (result.value );
178178 });
179179
180+ // Parameters can be: [[sql: string, arguments: any[] | arguments: any[][] ]]
181+ auto execSQLBatch = jsi::Function::createFromHostFunction (
182+ rt,
183+ jsi::PropNameID::forAscii (rt, " sequel_execSQLBatch" ),
184+ 2 ,
185+ [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value
186+ {
187+ if (sizeof (args) < 2 ) {
188+ jsi::detail::throwJSError (rt, " [react-native-quick-sqlite][execSQLBatch] - Incorrect parameter count" );
189+ return {};
190+ }
191+ const string dbName = args[0 ].asString (rt).utf8 (rt);
192+ const jsi::Value ¶ms = args[1 ];
193+ if (params.isNull () || params.isUndefined ())
194+ {
195+ jsi::detail::throwJSError (rt, " [react-native-quick-sqlite][execSQLBatch] - An array of SQL commands or parameters is needed" );
196+ return {};
197+ }
198+ int rowsAffected = 0 ;
199+ const jsi::Array &batchParams = params.asObject (rt).asArray (rt);
200+ try
201+ {
202+ sequel_execute (rt, dbName, " BEGIN TRANSACTION" , jsi::Value::undefined ());
203+ for (int i = 0 ; i<batchParams.length (rt); i++)
204+ {
205+ const jsi::Array &command = batchParams.getValueAtIndex (rt, i).asObject (rt).asArray (rt);
206+ if (command.length (rt) == 0 ) {
207+ sequel_execute (rt, dbName, " ROLLBACK" , jsi::Value::undefined ());
208+ jsi::detail::throwJSError (rt, " [react-native-quick-sqlite][execSQLBatch] - No SQL Commands found" );
209+ return {};
210+ }
211+ const string query = command.getValueAtIndex (rt, 0 ).asString (rt).utf8 (rt);
212+ const jsi::Value &commandParams = command.length (rt) > 1 ? command.getValueAtIndex (rt, 1 ) : jsi::Value::undefined ();
213+ if (!commandParams.isUndefined () && commandParams.asObject (rt).isArray (rt) && commandParams.asObject (rt).asArray (rt).length (rt) > 0 && commandParams.asObject (rt).asArray (rt).getValueAtIndex (rt, 0 ).isObject ())
214+ {
215+ // This arguments are an array of arrays, like a batch update of a single sql command.
216+ const jsi::Array &batchUpdateParams = commandParams.asObject (rt).asArray (rt);
217+ for (int x = 0 ; x<batchUpdateParams.length (rt); x++)
218+ {
219+ const jsi::Value &p = batchUpdateParams.getValueAtIndex (rt, x);
220+ SequelResult result = sequel_execute (rt, dbName, query, p);
221+ if (result.type == SequelResultError)
222+ {
223+ sequel_execute (rt, dbName, " ROLLBACK" , jsi::Value::undefined ());
224+ auto res = jsi::Object (rt);
225+ res.setProperty (rt, " status" , jsi::Value (1 ));
226+ res.setProperty (rt, " message" , jsi::String::createFromUtf8 (rt, result.message .c_str ()));
227+ return move (res);
228+ } else {
229+ if (result.value .getObject (rt).hasProperty (rt, jsi::PropNameID::forAscii (rt, " rowsAffected" )))
230+ {
231+ rowsAffected += result.value .getObject (rt).getProperty (rt, jsi::PropNameID::forAscii (rt, " rowsAffected" )).asNumber ();
232+ }
233+ }
234+ }
235+ } else {
236+ SequelResult result = sequel_execute (rt, dbName, query, commandParams);
237+ if (result.type == SequelResultError)
238+ {
239+ sequel_execute (rt, dbName, " ROLLBACK" , jsi::Value::undefined ());
240+ auto res = jsi::Object (rt);
241+ res.setProperty (rt, " status" , jsi::Value (1 ));
242+ res.setProperty (rt, " message" , jsi::String::createFromUtf8 (rt, result.message .c_str ()));
243+ return move (res);
244+ } else {
245+ if (result.value .getObject (rt).hasProperty (rt, jsi::PropNameID::forAscii (rt, " rowsAffected" )))
246+ {
247+ rowsAffected += result.value .getObject (rt).getProperty (rt, jsi::PropNameID::forAscii (rt, " rowsAffected" )).asNumber ();
248+ }
249+ }
250+ }
251+ }
252+ sequel_execute (rt, dbName, " COMMIT" , jsi::Value::undefined ());
253+ } catch (...) {
254+ sequel_execute (rt, dbName, " ROLLBACK" , jsi::Value::undefined ());
255+ }
256+ auto res = jsi::Object (rt);
257+ res.setProperty (rt, " status" , jsi::Value (0 ));
258+ res.setProperty (rt, " rowsAffected" , jsi::Value (rowsAffected));
259+ return move (res);
260+ });
261+
180262 // Async Execute SQL
181263 // auto asyncExecSQL = jsi::Function::createFromHostFunction(
182264 // rt,
@@ -220,6 +302,8 @@ void installSequel(jsi::Runtime &rt, const char *docPath)
220302 module .setProperty (rt, " delete" , move (remove));
221303
222304 module .setProperty (rt, " executeSql" , move (execSQL));
305+ module .setProperty (rt, " executeSqlBatch" , move (execSQLBatch));
306+
223307 // module.setProperty(rt, "backgroundExecuteSql", move(asyncExecSQL));
224308
225309 rt.global ().setProperty (rt, " sqlite" , move (module ));
0 commit comments