diff --git a/src/server/shared/datastore.php b/src/server/shared/datastore.php --- a/src/server/shared/datastore.php +++ b/src/server/shared/datastore.php @@ -101,6 +101,12 @@ $this->db->commit(); } +/** Abort an ongoing transaction. */ +public function rollback() +{ + $this->db->rollback(); +} + /** Verify the database schema, and fix if needed. */ public function checkSchema() { @@ -135,7 +141,7 @@ $res = $this->db->query('SELECT col_version FROM tbl_version'); if ($res === FALSE) { // restart transaction, so this fail doesn't block the following commands - $this->db->rollback(); + $this->rollback(); $this->beginTransaction(); return 0; } diff --git a/src/server/shared/product.php b/src/server/shared/product.php --- a/src/server/shared/product.php +++ b/src/server/shared/product.php @@ -148,7 +148,7 @@ $entry->delete($db, $this->productId); // delete data tables - $stmt = $db->prepare('DROP TABLE ' . $this->dataTableName()); + $stmt = $db->prepare('DROP TABLE ' . $this->dataTableName() . ($db->driver() == 'sqlite' ? '' : ' CASCADE')); $db->execute($stmt); // delete product diff --git a/src/server/shared/schemaentryelement.php b/src/server/shared/schemaentryelement.php --- a/src/server/shared/schemaentryelement.php +++ b/src/server/shared/schemaentryelement.php @@ -98,14 +98,23 @@ return; } - if ($this->schemaEntry->isScalar()) { - $stmt = $db->prepare('ALTER TABLE ' . $this->schemaEntry->product()->dataTableName() - . ' DROP COLUMN ' . $this->dataColumnName()); - $db->execute($stmt); - } else { - $stmt = $db->prepare('ALTER TABLE ' . $this->schemaEntry->dataTableName() - . ' DROP COLUMN ' . $this->dataColumnName()); - $db->execute($stmt); + try { + if ($this->schemaEntry->isScalar()) { + $stmt = $db->prepare('ALTER TABLE ' . $this->schemaEntry->product()->dataTableName() + . ' DROP COLUMN ' . $this->dataColumnName()); + $db->execute($stmt); + } else { + $stmt = $db->prepare('ALTER TABLE ' . $this->schemaEntry->dataTableName() + . ' DROP COLUMN ' . $this->dataColumnName()); + $db->execute($stmt); + } + } catch (RESTException $e) { + // don't fail hard on column removal, this can leave the db and our schema description in an inconsistent state + // or block product deletion entirely + error_log($e->getMessage()); + // restart transaction so this doesn't block subsequent queries + $db->rollBack(); + $db->beginTransaction(); } }