static void cg_schema_manage_triggers()

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);
}