From 0a6a2fe64508497d287aa3341e667fe313912774 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 25 Jul 2012 15:52:26 +0200 Subject: Simplify auto id implementation in Oracle Specifically, instead of using a trigger to assign the next id from the sequence, get the next value directly in the INSERT statement. --- odb/relational/oracle/context.cxx | 2 +- odb/relational/oracle/schema.cxx | 37 +++------------------------ odb/relational/oracle/source.cxx | 18 ++++++------- odb/relational/pgsql/source.cxx | 11 +------- odb/relational/source.cxx | 51 +++++++++++++++++++------------------ odb/relational/source.hxx | 53 +++++++++++++++++++++++---------------- 6 files changed, 71 insertions(+), 101 deletions(-) diff --git a/odb/relational/oracle/context.cxx b/odb/relational/oracle/context.cxx index c0a7199..01b690a 100644 --- a/odb/relational/oracle/context.cxx +++ b/odb/relational/oracle/context.cxx @@ -79,7 +79,7 @@ namespace relational generate_grow = false; need_alias_as = false; - insert_send_auto_id = true; + insert_send_auto_id = false; delay_freeing_statement_result = false; need_image_clone = true; data_->bind_vector_ = "oracle::bind*"; diff --git a/odb/relational/oracle/schema.cxx b/odb/relational/oracle/schema.cxx index bf040e0..ce2c470 100644 --- a/odb/relational/oracle/schema.cxx +++ b/odb/relational/oracle/schema.cxx @@ -114,7 +114,7 @@ namespace relational << " IF SQLCODE != -942 THEN RAISE; END IF;" << endl << " END;" << endl; - // Drop the sequence and trigger if we have auto primary key. + // Drop the sequence if we have auto primary key. // using sema_rel::primary_key; @@ -131,13 +131,6 @@ namespace relational << " EXCEPTION" << endl << " WHEN OTHERS THEN" << endl << " IF SQLCODE != -2289 THEN RAISE; END IF;" << endl - << " END;" << endl - << " BEGIN" << endl - << " EXECUTE IMMEDIATE 'DROP TRIGGER " << - quote_id (table + "_trg") << "';" << endl - << " EXCEPTION" << endl - << " WHEN OTHERS THEN" << endl - << " IF SQLCODE != -4080 THEN RAISE; END IF;" << endl << " END;" << endl; } @@ -283,7 +276,7 @@ namespace relational tables_.insert (t.name ()); // Add it before to cover self-refs. base::traverse (t); - // Create the sequence and trigger if we have auto primary key. + // Create the sequence if we have auto primary key. // using sema_rel::primary_key; @@ -294,33 +287,9 @@ namespace relational if (pk != 0 && pk->auto_ ()) { - qname const& tname (t.name ()); - string const& cname (pk->contains_begin ()->column ().name ()); - - qname seq_name (tname + "_seq"); - qname trg_name (tname + "_trg"); - - // Sequence. - // pre_statement (); - - os_ << "CREATE SEQUENCE " << quote_id (seq_name) << endl + os_ << "CREATE SEQUENCE " << quote_id (t.name () + "_seq") << endl << " START WITH 1 INCREMENT BY 1" << endl; - - post_statement (); - - // Trigger. - // - pre_statement (); - - os_ << "CREATE TRIGGER " << quote_id (trg_name) << endl - << " BEFORE INSERT ON " << quote_id (tname) << endl - << " FOR EACH ROW" << endl - << "BEGIN" << endl - << " SELECT " << quote_id (seq_name) << ".nextval " << - "INTO :new." << quote_id (cname) << " FROM DUAL;" << endl - << "END;" << endl; - post_statement (); } diff --git a/odb/relational/oracle/source.cxx b/odb/relational/oracle/source.cxx index cfbdbac..780dc06 100644 --- a/odb/relational/oracle/source.cxx +++ b/odb/relational/oracle/source.cxx @@ -19,10 +19,7 @@ namespace relational struct query_parameters: relational::query_parameters { - query_parameters (base const& x) - : base (x), i_ (0) - { - } + query_parameters (base const& x): base (x), i_ (0) {} virtual string next () @@ -33,6 +30,14 @@ namespace relational return ss.str (); } + virtual string + auto_id () + { + // The same sequence name as used in schema.cxx. + // + return quote_id (table_ + "_seq") + ".nextval"; + } + private: size_t i_; }; @@ -509,11 +514,6 @@ namespace relational class_ (base const& x): base (x) {} virtual void - init_auto_id (semantics::data_member&, string const&) - { - } - - virtual void init_image_pre (type& c) { if (options.generate_query () && diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx index a327b2a..c1ca854 100644 --- a/odb/relational/pgsql/source.cxx +++ b/odb/relational/pgsql/source.cxx @@ -21,10 +21,7 @@ namespace relational struct query_parameters: relational::query_parameters { - query_parameters (base const& x) - : base (x), i_ (0) - { - } + query_parameters (base const& x): base (x), i_ (0) {} virtual string next () @@ -601,12 +598,6 @@ namespace relational class_ (base const& x): base (x) {} virtual void - init_auto_id (semantics::data_member&, string const& im) - { - os << im << "value = 0;"; - } - - virtual void persist_statement_extra (type& c, relational::query_parameters&, persist_position p) diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx index 5338730..e97cdfe 100644 --- a/odb/relational/source.cxx +++ b/odb/relational/source.cxx @@ -477,7 +477,8 @@ traverse_object (type& c) // Statements. // - string const& table (table_qname (c)); + qname table (table_name (c)); + string qtable (quote_id (table)); // persist_statement // @@ -493,7 +494,7 @@ traverse_object (type& c) bool dv (sc.empty ()); // The DEFAULT VALUES syntax. os << "const char " << traits << "::persist_statement[] =" << endl - << strlit ("INSERT INTO " + table_qname(c) + (dv ? "" : " (")) << endl; + << strlit ("INSERT INTO " + qtable + (dv ? "" : " (")) << endl; for (statement_columns::const_iterator i (sc.begin ()), e (sc.end ()); i != e;) @@ -502,7 +503,7 @@ traverse_object (type& c) os << strlit (c + (++i != e ? "," : ")")) << endl; } - instance qp; + instance qp (table); persist_statement_extra (c, *qp, persist_after_columns); @@ -542,7 +543,7 @@ traverse_object (type& c) statement_columns sc; { statement_kind sk (statement_select); // Imperfect forwarding. - instance t (table, sk, sc, d); + instance t (qtable, sk, sc, d); t->traverse (c); process_statement_columns (sc, statement_select); find_column_counts[poly_depth - d] = sc.size (); @@ -557,7 +558,7 @@ traverse_object (type& c) os << strlit (c + (++i != e ? "," : "")) << endl; } - os << strlit (" FROM " + table) << endl; + os << strlit (" FROM " + qtable) << endl; if (poly_derived) { @@ -569,15 +570,15 @@ traverse_object (type& c) instance j (c, f, d); // @@ (im)perfect forwarding j->traverse (c); - instance qp; + instance qp (table); for (object_columns_list::iterator b (id_cols->begin ()), i (b); i != id_cols->end (); ++i) { if (i != b) os << endl; - os << strlit ((i == b ? " WHERE " : " AND ") + table + "." + - quote_id (i->name) + "=" + + os << strlit ((i == b ? " WHERE " : " AND ") + + qtable + "." + quote_id (i->name) + "=" + convert_to (qp->next (), i->type, *i->member)); } @@ -621,7 +622,7 @@ traverse_object (type& c) statement_columns sc; { statement_kind sk (statement_select); // Imperfect forwarding. - instance t (table, sk, sc); + instance t (qtable, sk, sc); t->traverse (*discriminator); if (optimistic != 0) @@ -641,17 +642,17 @@ traverse_object (type& c) os << strlit (c + (++i != e ? "," : "")) << endl; } - os << strlit (" FROM " + table) << endl; + os << strlit (" FROM " + qtable) << endl; - instance qp; + instance qp (table); for (object_columns_list::iterator b (id_cols->begin ()), i (b); i != id_cols->end (); ++i) { if (i != b) os << endl; - os << strlit ((i == b ? " WHERE " : " AND ") + table + "." + - quote_id (i->name) + "=" + + os << strlit ((i == b ? " WHERE " : " AND ") + + qtable + "." + quote_id (i->name) + "=" + convert_to (qp->next (), i->type, *i->member)); } @@ -663,7 +664,7 @@ traverse_object (type& c) // if (cc.total != cc.id + cc.inverse + cc.readonly) { - instance qp; + instance qp (table); statement_columns sc; { @@ -675,7 +676,7 @@ traverse_object (type& c) } os << "const char " << traits << "::update_statement[] =" << endl - << strlit ("UPDATE " + table + " SET ") << endl; + << strlit ("UPDATE " + qtable + " SET ") << endl; for (statement_columns::const_iterator i (sc.begin ()), e (sc.end ()); i != e;) @@ -706,9 +707,9 @@ traverse_object (type& c) // erase_statement // { - instance qp; + instance qp (table); os << "const char " << traits << "::erase_statement[] =" << endl - << strlit ("DELETE FROM " + table); + << strlit ("DELETE FROM " + qtable); for (object_columns_list::iterator b (id_cols->begin ()), i (b); i != id_cols->end (); ++i) @@ -726,11 +727,11 @@ traverse_object (type& c) if (optimistic != 0 && !poly_derived) { - instance qp; + instance qp (table); os << "const char " << traits << "::optimistic_erase_statement[] " << "=" << endl - << strlit ("DELETE FROM " + table); + << strlit ("DELETE FROM " + qtable); for (object_columns_list::iterator b (id_cols->begin ()), i (b); i != id_cols->end (); ++i) @@ -755,7 +756,7 @@ traverse_object (type& c) statement_columns sc; { statement_kind sk (statement_select); // Imperfect forwarding. - instance oc (table, sk, sc, poly_depth); + instance oc (qtable, sk, sc, poly_depth); oc->traverse (c); process_statement_columns (sc, statement_select); } @@ -770,7 +771,7 @@ traverse_object (type& c) os << strlit (c + (++i != e ? "," : "")) << endl; } - os << strlit (" FROM " + table) << endl; + os << strlit (" FROM " + qtable) << endl; if (poly_derived) { @@ -791,13 +792,13 @@ traverse_object (type& c) // erase_query_statement // os << "const char " << traits << "::erase_query_statement[] =" << endl - << strlit ("DELETE FROM " + table) << endl; + << strlit ("DELETE FROM " + qtable) << endl; // DELETE JOIN: // // MySQL: - // << strlit ("DELETE FROM " + table + " USING " + table) << endl; - // << strlit ("DELETE " + table + " FROM " + table) << endl; + // << strlit ("DELETE FROM " + qtable + " USING " + qtable) << endl; + // << strlit ("DELETE " + qtable + " FROM " + qtable) << endl; // oj->write (); // @@ -807,7 +808,7 @@ traverse_object (type& c) // table_name // os << "const char " << traits << "::table_name[] =" << endl - << strlit (table_qname (c)) << ";" // Use quoted name. + << strlit (qtable) << ";" // Use quoted name. << endl; } diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index 7ee8a06..2b2c90e 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -55,6 +55,8 @@ namespace relational { typedef query_parameters base; + query_parameters (qname const& table): table_ (table) {} + virtual string next () { @@ -66,6 +68,9 @@ namespace relational { return next (); } + + protected: + qname table_; }; struct object_columns: object_columns_base, virtual context @@ -1790,7 +1795,8 @@ namespace relational { semantics::type& idt (container_idt (m)); - string table (table_qname (m, table_prefix_)); + qname table (table_name (m, table_prefix_)); + string qtable (quote_id (table)); instance id_cols; // select_all_statement @@ -1803,7 +1809,8 @@ namespace relational semantics::class_* c (object_pointer (vt)); semantics::data_member& inv_id (*id_member (*c)); - string inv_table; // Other table name. + qname inv_table; // Other table name. + string inv_qtable; instance inv_id_cols; // Other id column. instance inv_fid_cols; // Other foreign id // column (ref to us). @@ -1820,7 +1827,8 @@ namespace relational table_prefix tp (schema (c->scope ()), table_name_prefix (c->scope ()), table_name (*c) + "_"); - inv_table = table_qname (*im, tp); + inv_table = table_name (*im, tp); + inv_qtable = quote_id (inv_table); inv_id_cols->traverse (*im, utype (inv_id), "id", "object_id", c); inv_fid_cols->traverse (*im, idt, "value", "value"); @@ -1833,8 +1841,8 @@ namespace relational // sc.push_back ( statement_column ( - inv_table, - inv_table + "." + quote_id (i->name), + inv_qtable, + inv_qtable + "." + quote_id (i->name), i->type, *i->member, inv_id_cols->size () == 1 ? "id" : "")); @@ -1844,7 +1852,8 @@ namespace relational { // many(i)-to-one // - inv_table = table_qname (*c); + inv_table = table_name (*c); + inv_qtable = quote_id (inv_table); inv_id_cols->traverse (inv_id); inv_fid_cols->traverse (*im); @@ -1854,8 +1863,8 @@ namespace relational { sc.push_back ( statement_column ( - inv_table, - inv_table + "." + quote_id (i->name), + inv_qtable, + inv_qtable + "." + quote_id (i->name), i->type, *i->member)); } @@ -1872,15 +1881,15 @@ namespace relational os << strlit (c + (++i != e ? "," : "")) << endl; } - instance qp; - os << strlit (" FROM " + inv_table); + instance qp (inv_table); + os << strlit (" FROM " + inv_qtable); for (object_columns_list::iterator b (inv_fid_cols->begin ()), i (b); i != inv_fid_cols->end (); ++i) { os << endl - << strlit ((i == b ? " WHERE " : " AND ") + inv_table + "." + - quote_id (i->name) + "=" + + << strlit ((i == b ? " WHERE " : " AND ") + + inv_qtable + "." + quote_id (i->name) + "=" + convert_to (qp->next (), i->type, *i->member)); } } @@ -1890,7 +1899,7 @@ namespace relational statement_columns sc; statement_kind sk (statement_select); // Imperfect forwarding. - instance t (table, sk, sc); + instance t (qtable, sk, sc); switch (ck) { @@ -1926,15 +1935,15 @@ namespace relational os << strlit (c + (++i != e ? "," : "")) << endl; } - instance qp; - os << strlit (" FROM " + table); + instance qp (table); + os << strlit (" FROM " + qtable); for (object_columns_list::iterator b (id_cols->begin ()), i (b); i != id_cols->end (); ++i) { os << endl - << strlit ((i == b ? " WHERE " : " AND ") + table + "." + - quote_id (i->name) + "=" + + << strlit ((i == b ? " WHERE " : " AND ") + + qtable + "." + quote_id (i->name) + "=" + convert_to (qp->next (), i->type, *i->member)); } @@ -1943,7 +1952,7 @@ namespace relational string const& col (column_qname (m, "index", "index")); os << endl - << strlit (" ORDER BY " + table + "." + col); + << strlit (" ORDER BY " + qtable + "." + col); } } @@ -1991,7 +2000,7 @@ namespace relational process_statement_columns (sc, statement_insert); - os << strlit ("INSERT INTO " + table + " (") << endl; + os << strlit ("INSERT INTO " + qtable + " (") << endl; for (statement_columns::const_iterator i (sc.begin ()), e (sc.end ()); i != e;) @@ -2001,7 +2010,7 @@ namespace relational } string values; - instance qp; + instance qp (table); for (statement_columns::const_iterator b (sc.begin ()), i (b), e (sc.end ()); i != e; ++i) { @@ -2025,9 +2034,9 @@ namespace relational << endl; else { - instance qp; + instance qp (table); - os << strlit ("DELETE FROM " + table); + os << strlit ("DELETE FROM " + qtable); for (object_columns_list::iterator b (id_cols->begin ()), i (b); i != id_cols->end (); ++i) -- cgit v1.1