@@ -296,7 +296,7 @@ class genproc_t
296296
297297 int app_run_gen ()
298298 {
299- log_debug (" Running configured generalizer (run {}) ..." , ++m_gen_run );
299+ log_debug (" Configuring generalizer..." );
300300
301301 if (lua_type (lua_state (), 1 ) != LUA_TSTRING) {
302302 throw std::runtime_error{" Argument #1 to 'run_gen' must be a "
@@ -326,15 +326,16 @@ class genproc_t
326326 auto generalizer =
327327 create_generalizer (strategy, &db_connection, ¶ms);
328328
329- log_debug ( " Generalizer '{}' ({}) initialized ." , generalizer->name (),
330- generalizer->strategy ());
329+ log_info ( " Running generalizer '{}' ({}).. ." , generalizer->name (),
330+ generalizer->strategy ());
331331
332332 if (m_append) {
333333 params.set (" delete_existing" , true );
334334 }
335335
336336 write_to_debug_log (params, " Params (after initialization):" );
337337
338+ util::timer_t timer_gen;
338339 if (generalizer->on_tiles ()) {
339340 process_tiles (db_connection, params, generalizer.get ());
340341 } else {
@@ -353,8 +354,8 @@ class genproc_t
353354 std::chrono::duration_cast<std::chrono::milliseconds>(
354355 timer.elapsed ())));
355356 }
356- log_debug (" Finished generalizer '{}' (run {}) ." , generalizer->name (),
357- m_gen_run );
357+ log_info (" Finished generalizer '{}' in {}." , generalizer->name (),
358+ util::human_readable_duration (timer_gen. stop ()) );
358359
359360 return 0 ;
360361 }
@@ -368,16 +369,50 @@ class genproc_t
368369
369370 std::string const description =
370371 luaX_get_table_string (lua_state (), " description" , 1 , " Argument #1" );
371- std::string const sql =
372- luaX_get_table_string (lua_state (), " sql" , 1 , " Argument #1" );
373372
374- log_debug (" Running SQL command: {}." , description);
373+ bool const transaction = luaX_get_table_bool (lua_state (), " transaction" ,
374+ 1 , " Argument #1" , false );
375+
376+ std::vector<std::string> queries;
377+ if (transaction) {
378+ queries.emplace_back (" BEGIN" );
379+ }
380+
381+ lua_getfield (lua_state (), 1 , " sql" );
382+ int const ltype = lua_type (lua_state (), -1 );
383+ if (ltype == LUA_TSTRING) {
384+ queries.emplace_back (lua_tostring (lua_state (), -1 ));
385+ } else if (ltype == LUA_TTABLE) {
386+ if (!luaX_is_array (lua_state ())) {
387+ throw std::runtime_error{
388+ " Table in 'sql' field must be an array." };
389+ }
390+ luaX_for_each (lua_state (), [&]() {
391+ if (lua_type (lua_state (), -1 ) != LUA_TSTRING) {
392+ throw std::runtime_error{
393+ " Table in 'sql' field must only contain strings." };
394+ }
395+ queries.emplace_back (lua_tostring (lua_state (), -1 ));
396+ });
397+ } else {
398+ throw std::runtime_error{
399+ " Argument #1 must contain a 'sql' string or table field." };
400+ }
401+
402+ if (transaction) {
403+ queries.emplace_back (" COMMIT" );
404+ }
405+
406+ log_info (" Running SQL commands: {}." , description);
375407
376408 util::timer_t timer_sql;
377409 pg_conn_t const db_connection{m_conninfo};
378- db_connection.exec (sql);
379- log_debug (" SQL command took {}." ,
380- util::human_readable_duration (timer_sql.stop ()));
410+ for (auto const &query : queries) {
411+ log_debug (" Running sql: {}" , query);
412+ db_connection.exec (query);
413+ }
414+ log_info (" Finished SQL commands in {}." ,
415+ util::human_readable_duration (timer_sql.stop ()));
381416
382417 return 0 ;
383418 }
@@ -504,7 +539,6 @@ class genproc_t
504539
505540 std::string m_conninfo;
506541 std::string m_dbschema;
507- std::size_t m_gen_run = 0 ;
508542 uint32_t m_jobs;
509543 bool m_append;
510544 bool m_updatable;
0 commit comments