Move table out the way, return columns. * Note: with db_hook, frees tmpctx! */
| 466 | /* Move table out the way, return columns. |
| 467 | * Note: with db_hook, frees tmpctx! */ |
| 468 | static char **prepare_table_manip(const tal_t *ctx, |
| 469 | struct db *db, const char *tablename) |
| 470 | { |
| 471 | sqlite3_stmt *stmt; |
| 472 | const char *sql; |
| 473 | char *cmd, *bracket; |
| 474 | char **parts; |
| 475 | int err; |
| 476 | struct db_sqlite3 *wrapper = (struct db_sqlite3 *)db->conn; |
| 477 | |
| 478 | /* Get schema. */ |
| 479 | sqlite3_prepare_v2(wrapper->conn, "SELECT sql FROM sqlite_master WHERE type = ? AND name = ?;", -1, &stmt, NULL); |
| 480 | sqlite3_bind_text(stmt, 1, "table", strlen("table"), SQLITE_TRANSIENT); |
| 481 | sqlite3_bind_text(stmt, 2, tablename, strlen(tablename), SQLITE_TRANSIENT); |
| 482 | |
| 483 | err = sqlite3_step(stmt); |
| 484 | if (err != SQLITE_ROW) { |
| 485 | db->error = tal_fmt(db, "getting schema: %s", |
| 486 | sqlite3_errmsg(wrapper->conn)); |
| 487 | sqlite3_finalize(stmt); |
| 488 | return NULL; |
| 489 | } |
| 490 | |
| 491 | sql = tal_strdup(tmpctx, (const char *)sqlite3_column_text(stmt, 0)); |
| 492 | sqlite3_finalize(stmt); |
| 493 | |
| 494 | /* We MUST use generic routines to write to db, since they |
| 495 | * mirror changes to the db hook! */ |
| 496 | bracket = strchr(sql, '('); |
| 497 | if (!strstarts(sql, "CREATE TABLE") || !bracket) |
| 498 | db_fatal("Bad sql from prepare_table_manip %s: %s", |
| 499 | tablename, sql); |
| 500 | |
| 501 | /* Split after ( by commas: any lower case is assumed to be a field */ |
| 502 | parts = tal_strsplit(ctx, bracket + 1, ",", STR_EMPTY_OK); |
| 503 | |
| 504 | /* Now, we actually need to turn OFF transactions for a moment, as |
| 505 | * this pragma only has an effect outside a tx! */ |
| 506 | db_commit_transaction(db); |
| 507 | |
| 508 | /* But core insists we're "in a transaction" for all ops, so fake it */ |
| 509 | db->in_transaction = "Not really"; |
| 510 | /* Turn off foreign keys first. */ |
| 511 | db_prepare_for_changes(db); |
| 512 | db_exec_prepared_v2(take(db_prepare_untranslated(db, |
| 513 | "PRAGMA foreign_keys = OFF;"))); |
| 514 | db_report_changes(db, NULL, 0); |
| 515 | db->in_transaction = NULL; |
| 516 | |
| 517 | db_begin_transaction(db); |
| 518 | cmd = tal_fmt(tmpctx, "ALTER TABLE %s RENAME TO temp_%s;", |
| 519 | tablename, tablename); |
| 520 | db_exec_prepared_v2(take(db_prepare_untranslated(db, cmd))); |
| 521 | |
| 522 | return parts; |
| 523 | } |
| 524 | |
| 525 | static bool complete_table_manip(struct db *db, |
no test coverage detected