in sources/cg_schema.c [720:810]
static void cg_schema_manage_triggers(charbuf *output, int32_t *drops, int32_t *creates) {
Contract(creates);
Contract(drops);
CHARBUF_OPEN(create);
CHARBUF_OPEN(drop);
// non-null-callbacks will generate SQL for Sqlite (no attributes)
gen_sql_callbacks callbacks;
init_gen_sql_callbacks(&callbacks);
callbacks.mode = gen_mode_no_annotations;
*creates = 0;
*drops = 0;
for (list_item *item = all_triggers_list; item; item = item->next) {
ast_node *ast = item->ast;
Invariant(is_ast_create_trigger_stmt(ast));
if (!include_from_region(ast->sem->region, SCHEMA_TO_UPGRADE)) {
continue;
}
EXTRACT_OPTION(flags, ast->left);
EXTRACT_NOTNULL(trigger_body_vers, ast->right);
EXTRACT_NOTNULL(trigger_def, trigger_body_vers->left);
EXTRACT_ANY_NOTNULL(trigger_name_ast, trigger_def->left);
EXTRACT_STRING(name, trigger_name_ast);
if (flags & TRIGGER_IS_TEMP) {
continue;
}
bprintf(&drop, " DROP TRIGGER IF EXISTS %s;\n", name);
(*drops)++;
// if not deleted, emit the create
if (ast->sem->delete_version < 0) {
gen_set_output_buffer(&create);
gen_statement_with_callbacks(ast, &callbacks);
bprintf(&create, ";\n");
(*creates)++;
}
}
if (options.schema_exclusive) {
bprintf(output, "\n-- get all the trigger names, store them in a result set\n");
bprintf(output, "@attribute(cql:private)\n");
bprintf(output, "CREATE PROCEDURE %s_cql_get_all_triggers()\n", global_proc_name);
bprintf(output, "BEGIN\n");
bprintf(output, " DECLARE C CURSOR FOR SELECT name from sqlite_master where type = 'trigger';\n");
bprintf(output, " LOOP FETCH C\n");
bprintf(output, " BEGIN\n");
bprintf(output, " OUT UNION C;\n");
bprintf(output, " END;\n");
bprintf(output, "END;\n\n");
bprintf(output, "-- drop all the triggers using the fetched names\n");
bprintf(output, "@attribute(cql:private)\n");
bprintf(output, "CREATE PROCEDURE %s_cql_drop_all_triggers()\n", global_proc_name);
bprintf(output, "BEGIN\n");
bprintf(output, " DECLARE C CURSOR FOR CALL %s_cql_get_all_triggers();\n", global_proc_name);
bprintf(output, " LOOP FETCH C\n");
bprintf(output, " BEGIN\n");
bprintf(output, " CALL cql_exec_internal(printf('DROP TRIGGER %%s;', C.name));\n");
bprintf(output, " END;\n");
bprintf(output, "END;\n\n");
// we always behave as though we have some drops in exclusive mode
*drops = 1;
}
else if (*drops) {
bprintf(output, "-- drop all the triggers we know\n");
bprintf(output, "@attribute(cql:private)\n");
bprintf(output, "CREATE PROCEDURE %s_cql_drop_all_triggers()\n", global_proc_name);
bprintf(output, "BEGIN\n");
bprintf(output, "%s", drop.ptr);
bprintf(output, "END;\n\n");
}
if (*creates) {
bprintf(output, "-- create all the triggers we know\n");
bprintf(output, "@attribute(cql:private)\n");
bprintf(output, "CREATE PROCEDURE %s_cql_create_all_triggers()\n", global_proc_name);
bprintf(output, "BEGIN\n");
bindent(output, &create, 2);
bprintf(output, "END;\n\n");
}
CHARBUF_CLOSE(drop);
CHARBUF_CLOSE(create);
}