From 3417fc7c0df3b1b01750874587c4f3bb2ef02f45 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 4 Dec 2013 11:30:33 +0200 Subject: Implement on_delete pragma for object pointers Translates to the ON DELETE SQL clause. --- odb/relational/mssql/schema.cxx | 19 +++++++++++++++++++ odb/relational/mysql/schema.cxx | 18 ++++++++++++++++++ odb/relational/schema.hxx | 10 ++++++++-- odb/relational/validator.cxx | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) (limited to 'odb/relational') diff --git a/odb/relational/mssql/schema.cxx b/odb/relational/mssql/schema.cxx index 2480e75..7b6c7ca 100644 --- a/odb/relational/mssql/schema.cxx +++ b/odb/relational/mssql/schema.cxx @@ -237,6 +237,20 @@ namespace relational { create_foreign_key (base const& x): base (x) {} + void + diagnose (sema_rel::foreign_key& fk) + { + if (fk.on_delete () != sema_rel::foreign_key::no_action) + { + cerr << "warning: foreign key '" << fk.name () << "' has " << + "ON DELETE clause but is disabled in SQL Server due to lack " + "of deferrable constraint support" << endl; + + cerr << "info: consider using non-deferrable foreign keys (" << + "--fkeys-deferrable-mode)" << endl; + } + } + virtual void traverse_create (sema_rel::foreign_key& fk) { @@ -248,6 +262,8 @@ namespace relational base::traverse_create (fk); else { + diagnose (fk); + // Don't bloat C++ code with comment strings if we are // generating embedded schema. // @@ -268,6 +284,9 @@ namespace relational { bool c (!fk.not_deferrable () && !in_comment); + if (c) + diagnose (fk); + if (c && format_ != schema_format::sql) return; diff --git a/odb/relational/mysql/schema.cxx b/odb/relational/mysql/schema.cxx index f06914a..473e746 100644 --- a/odb/relational/mysql/schema.cxx +++ b/odb/relational/mysql/schema.cxx @@ -145,6 +145,20 @@ namespace relational { create_foreign_key (base const& x): base (x) {} + void + diagnose (sema_rel::foreign_key& fk) + { + if (fk.on_delete () != sema_rel::foreign_key::no_action) + { + cerr << "warning: foreign key '" << fk.name () << "' has " << + "ON DELETE clause but is disabled in MySQL due to lack " + "of deferrable constraint support" << endl; + + cerr << "info: consider using non-deferrable foreign keys (" << + "--fkeys-deferrable-mode)" << endl; + } + } + virtual void traverse_create (sema_rel::foreign_key& fk) { @@ -156,6 +170,8 @@ namespace relational base::traverse_create (fk); else { + diagnose (fk); + // Don't bloat C++ code with comment strings if we are // generating embedded schema. // @@ -178,6 +194,8 @@ namespace relational base::traverse_add (fk); else { + diagnose (fk); + if (format_ != schema_format::sql) return; diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx index 0de7036..4903e3a 100644 --- a/odb/relational/schema.hxx +++ b/odb/relational/schema.hxx @@ -857,14 +857,20 @@ namespace relational switch (a) { + case foreign_key::no_action: + break; case foreign_key::cascade: { os << endl << " ON DELETE CASCADE"; break; } - case foreign_key::no_action: - break; + case foreign_key::set_null: + { + os << endl + << " ON DELETE SET NULL"; + break; + } } } diff --git a/odb/relational/validator.cxx b/odb/relational/validator.cxx index c620a58..3218b57 100644 --- a/odb/relational/validator.cxx +++ b/odb/relational/validator.cxx @@ -51,6 +51,44 @@ namespace relational } } } + + // Check on-delete. + // + if (m.count ("on-delete")) + { + const char* kp (container (m) ? "value" : ""); + location l (m.location ()); + + // Make sure it is a pointer. + // + if (!object_pointer (member_utype (m, kp))) + { + error (l) << "on_delete specified for non-object pointer" << endl; + valid_ = false; + } + + // Make sure it is not inverse. + // + if (inverse (m, kp)) + { + error (l) << "on_delete specified for inverse object " << + "pointer" << endl; + valid_ = false; + } + + // Make sure the pointer is nullable if asked to set it to NULL. + // + using sema_rel::foreign_key; + + if (m.get ("on-delete") == + foreign_key::set_null && + !null (m, kp)) + { + error (l) << "set_null specified for non-nullable object " + "pointer" << endl; + valid_ = false; + } + } } bool& valid_; -- cgit v1.1