From 51956f409ec7ebea8b6790b0c5d4f0b51513d683 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 15 Sep 2013 12:46:09 +0200 Subject: Cleanup polymorphic base tables when dropping derived one --- odb/relational/sqlite/schema.cxx | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'odb/relational/sqlite') diff --git a/odb/relational/sqlite/schema.cxx b/odb/relational/sqlite/schema.cxx index c4d852d..24bc2ef 100644 --- a/odb/relational/sqlite/schema.cxx +++ b/odb/relational/sqlite/schema.cxx @@ -49,7 +49,48 @@ namespace relational if (pass_ != 2) return; - drop (t.name (), migration); + // Polymorphic base cleanup code. Because we cannot drop foreign + // keys, we will trigger cascade deletion. The only way to work + // around this problem is to delete from the root table and rely + // on the cascade to clean up the rest. + // + if (migration && + t.extra ().count ("kind") != 0 && + t.extra ()["kind"] == "polymorphic") + { + using sema_rel::model; + using sema_rel::table; + using sema_rel::primary_key; + using sema_rel::foreign_key; + + model& m (dynamic_cast (t.scope ())); + + table* p (&t); + do + { + // The polymorphic link is the first primary key. + // + for (table::names_iterator i (p->names_begin ()); + i != p->names_end (); ++i) + { + if (foreign_key* fk = dynamic_cast ( + &i->nameable ())) + { + p = m.find (fk->referenced_table ()); + assert (p != 0); // Base table should be there. + break; + } + } + } + while (p->extra ().count ("kind") != 0); + + primary_key& rkey (*p->find ("")); + primary_key& dkey (*t.find ("")); + assert (rkey.contains_size () == dkey.contains_size ()); + delete_ (p->name (), t.name (), rkey, dkey); + } + + drop (t, migration); } }; entry drop_table_; -- cgit v1.1