summaryrefslogtreecommitdiff
path: root/odb/relational/sqlite
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-09-15 12:46:09 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-09-15 12:46:09 +0200
commit51956f409ec7ebea8b6790b0c5d4f0b51513d683 (patch)
tree66f30e68fa3c8080d0d3d8d50c30e11914fc82b9 /odb/relational/sqlite
parentd9ea777539b166c7347c44a6b7784626405bc029 (diff)
Cleanup polymorphic base tables when dropping derived one
Diffstat (limited to 'odb/relational/sqlite')
-rw-r--r--odb/relational/sqlite/schema.cxx43
1 files changed, 42 insertions, 1 deletions
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<model&> (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<foreign_key*> (
+ &i->nameable ()))
+ {
+ p = m.find<table> (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> (""));
+ primary_key& dkey (*t.find<primary_key> (""));
+ assert (rkey.contains_size () == dkey.contains_size ());
+ delete_ (p->name (), t.name (), rkey, dkey);
+ }
+
+ drop (t, migration);
}
};
entry<drop_table> drop_table_;