aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-09-28 10:51:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-09-28 10:51:12 +0200
commit12aa1b18d99b51e513e9e82c0ed45717d7538ca0 (patch)
treea7e6c080dce069d7093130372954211a66e03474
parent5e7e037dd8c593e727f5a9672a2564257194cb48 (diff)
Make schema version access (but not modification) thread-safe
Also cache the version in statements so that we don't have to lock the mutex (slow) every time we need to check the version.
-rw-r--r--odb/relational/inline.hxx6
-rw-r--r--odb/relational/source.cxx190
-rw-r--r--odb/relational/source.hxx8
3 files changed, 105 insertions, 99 deletions
diff --git a/odb/relational/inline.hxx b/odb/relational/inline.hxx
index 95b4328..d1a4393 100644
--- a/odb/relational/inline.hxx
+++ b/odb/relational/inline.hxx
@@ -235,12 +235,6 @@ namespace relational
bool versioned (context::versioned (c));
- // Schema name as a string literal or empty.
- //
- string schema_name (options.schema_name ()[db]);
- if (!schema_name.empty ())
- schema_name = strlit (schema_name);
-
string const& type (class_fq_name (c));
string traits ("access::object_traits_impl< " + type + ", id_" +
db.string () + " >");
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index 366120c..b12bce3 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -1150,19 +1150,20 @@ traverse_object (type& c)
<< "throw abstract_class ();"
<< endl;
+ os << db << "::connection& conn (" << endl
+ << db << "::transaction::current ().connection ());"
+ << "statements_type& sts (" << endl
+ << "conn.statement_cache ().find_object<object_type> ());";
+
if (versioned ||
persist_versioned_containers ||
uss.count (user_sections::count_new |
user_sections::count_all |
user_sections::count_versioned_only) != 0)
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
+ "sts.version_migration (" << schema_name << "));";
- os << db << "::connection& conn (" << endl
- << db << "::transaction::current ().connection ());"
- << "statements_type& sts (" << endl
- << "conn.statement_cache ().find_object<object_type> ());"
- << endl;
+ os << endl;
// Call callback (pre_persist).
//
@@ -1502,12 +1503,24 @@ traverse_object (type& c)
<< endl;
}
+ bool sts (false);
+
if ((versioned && update_columns) ||
update_versioned_containers ||
versioned_sections)
+ {
+ sts = true;
+ os << db << "::transaction& tr (" << db <<
+ "::transaction::current ());"
+ << db << "::connection& conn (tr.connection ());"
+ << "statements_type& sts (" << endl
+ << "conn.statement_cache ().find_object<object_type> ());"
+ << endl;
+
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));"
+ "sts.version_migration (" << schema_name << "));"
<< endl;
+ }
// If we have change-updated sections that contain change-tracking
// containers, then mark such sections as changed if any of the
@@ -1587,10 +1600,10 @@ traverse_object (type& c)
{
bool readonly_base (context::readonly (*poly_base));
- if (readonly_base ||
- update_columns ||
- update_containers ||
- sections)
+ if (!sts && (readonly_base ||
+ update_columns ||
+ update_containers ||
+ sections))
{
os << db << "::transaction& tr (" << db <<
"::transaction::current ());"
@@ -1685,12 +1698,13 @@ traverse_object (type& c)
}
else if (update_columns)
{
- os << db << "::transaction& tr (" << db <<
- "::transaction::current ());"
- << db << "::connection& conn (tr.connection ());"
- << "statements_type& sts (" << endl
- << "conn.statement_cache ().find_object<object_type> ());"
- << endl;
+ if (!sts)
+ os << db << "::transaction& tr (" << db <<
+ "::transaction::current ());"
+ << db << "::connection& conn (tr.connection ());"
+ << "statements_type& sts (" << endl
+ << "conn.statement_cache ().find_object<object_type> ());"
+ << endl;
// Initialize id image.
//
@@ -1800,12 +1814,13 @@ traverse_object (type& c)
// to initialize the id image if we are polymorphic or have
// any containers or sections.
//
- os << db << "::transaction& tr (" << db <<
- "::transaction::current ());"
- << db << "::connection& conn (tr.connection ());"
- << "statements_type& sts (" << endl
- << "conn.statement_cache ().find_object<object_type> ());"
- << endl;
+ if (!sts)
+ os << db << "::transaction& tr (" << db <<
+ "::transaction::current ());"
+ << db << "::connection& conn (tr.connection ());"
+ << "statements_type& sts (" << endl
+ << "conn.statement_cache ().find_object<object_type> ());"
+ << endl;
// The same rationale as a couple of screens up.
//
@@ -2155,7 +2170,7 @@ traverse_object (type& c)
if (erase_versioned_containers)
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
+ "sts.version_migration (" << schema_name << "));";
os << endl;
@@ -2313,7 +2328,7 @@ traverse_object (type& c)
if (erase_versioned_containers)
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
+ "sts.version_migration (" << schema_name << "));";
os << endl;
@@ -2409,7 +2424,7 @@ traverse_object (type& c)
if (versioned)
{
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));"
+ "sts.version_migration (" << schema_name << "));"
<< endl;
svm = true;
}
@@ -2444,7 +2459,7 @@ traverse_object (type& c)
if (erase_versioned_containers && !svm)
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
+ "sts.version_migration (" << schema_name << "));";
os << endl;
@@ -2534,15 +2549,15 @@ traverse_object (type& c)
os << "}";
- if (versioned)
- os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
<< "conn.statement_cache ().find_object<object_type> ());";
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
if (poly_derived)
os << "root_statements_type& rsts (sts.root_statements ());";
@@ -2727,15 +2742,15 @@ traverse_object (type& c)
if (!abst)
{
- if (versioned)
- os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
<< "conn.statement_cache ().find_object<object_type> ());";
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
if (poly_derived)
os << "root_statements_type& rsts (sts.root_statements ());";
@@ -2833,15 +2848,15 @@ traverse_object (type& c)
if (!abst)
{
- if (versioned)
- os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
<< "conn.statement_cache ().find_object<object_type> ());";
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
if (poly_derived)
os << "root_statements_type& rsts (sts.root_statements ());";
@@ -3407,9 +3422,8 @@ traverse_object (type& c)
user_sections::count_all |
user_sections::count_versioned_only) != 0))
{
- os << "const schema_version_migration& svm (" << endl
- << "sts.connection ().database ().schema_version_migration (" <<
- schema_name << "));"
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));"
<< endl;
}
@@ -3529,7 +3543,7 @@ traverse_object (type& c)
if (versioned)
os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));"
+ "sts.version_migration (" << schema_name << "));"
<< endl;
// Avoid trying to execute an empty SELECT statement.
@@ -3746,25 +3760,24 @@ traverse_object (type& c)
//
os << "result< " << traits << "::object_type >" << endl
<< traits << "::" << endl
- << "query (database& db, const query_base_type& q)"
+ << "query (database&, const query_base_type& q)"
<< "{"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl
<< "using namespace " << db << ";"
<< "using odb::details::shared;"
<< "using odb::details::shared_ptr;"
<< endl;
- if (versioned)
- os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< endl
<< "statements_type& sts (" << endl
- << "conn.statement_cache ().find_object<object_type> ());"
- << endl;
+ << "conn.statement_cache ().find_object<object_type> ());";
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
+ os << endl;
// Rebind the image if necessary.
//
@@ -3883,17 +3896,17 @@ traverse_object (type& c)
<< "using odb::details::shared_ptr;"
<< endl;
- if (versioned)
- os << "const schema_version_migration& svm (" << endl
- << "c.database ().schema_version_migration (" <<
- schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< "static_cast<" << db << "::connection&> (c));"
<< endl
<< "statements_type& sts (" << endl
- << "conn.statement_cache ().find_object<object_type> ());"
- << endl;
+ << "conn.statement_cache ().find_object<object_type> ());";
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
+ os << endl;
// Rebind the image if necessary.
//
@@ -3975,11 +3988,6 @@ traverse_object (type& c)
<< "static_cast<select_statement*> (pq.stmt.get ())));"
<< endl;
- if (versioned)
- os << "const schema_version_migration& svm (" << endl
- << "st->connection ().database ().schema_version_migration (" <<
- schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< endl
@@ -3989,8 +3997,13 @@ traverse_object (type& c)
<< "assert (&conn == &st->connection ());"
<< endl
<< "statements_type& sts (" << endl
- << "conn.statement_cache ().find_object<object_type> ());"
- << endl;
+ << "conn.statement_cache ().find_object<object_type> ());";
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
+ os << endl;
// Rebind the image if necessary.
//
@@ -4960,24 +4973,23 @@ traverse_view (type& c)
{
os << "result< " << traits << "::view_type >" << endl
<< traits << "::" << endl
- << "query (database& db, const query_base_type& q)"
+ << "query (database&, const query_base_type& q)"
<< "{"
- << "ODB_POTENTIALLY_UNUSED (db);"
- << endl
<< "using namespace " << db << ";"
<< "using odb::details::shared;"
<< "using odb::details::shared_ptr;"
<< endl;
- if (versioned)
- os << "const schema_version_migration& svm (" <<
- "db.schema_version_migration (" << schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< "statements_type& sts (" << endl
- << "conn.statement_cache ().find_view<view_type> ());"
- << endl
+ << "conn.statement_cache ().find_view<view_type> ());";
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
+ os << endl
<< "image_type& im (sts.image ());"
<< "binding& imb (sts.image_binding ());"
<< endl
@@ -5039,16 +5051,16 @@ traverse_view (type& c)
<< "using odb::details::shared_ptr;"
<< endl;
- if (versioned)
- os << "const schema_version_migration& svm (" << endl
- << "c.database ().schema_version_migration (" <<
- schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< "static_cast<" << db << "::connection&> (c));"
<< "statements_type& sts (" << endl
- << "conn.statement_cache ().find_view<view_type> ());"
- << endl;
+ << "conn.statement_cache ().find_view<view_type> ());";
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
+ os << endl;
// Rebind the image if necessary.
//
@@ -5109,11 +5121,6 @@ traverse_view (type& c)
<< "static_cast<select_statement*> (pq.stmt.get ())));"
<< endl;
- if (versioned)
- os << "const schema_version_migration& svm (" << endl
- << "st->connection ().database ().schema_version_migration (" <<
- schema_name << "));";
-
os << db << "::connection& conn (" << endl
<< db << "::transaction::current ().connection ());"
<< endl
@@ -5123,8 +5130,13 @@ traverse_view (type& c)
<< "assert (&conn == &st->connection ());"
<< endl
<< "statements_type& sts (" << endl
- << "conn.statement_cache ().find_view<view_type> ());"
- << endl;
+ << "conn.statement_cache ().find_view<view_type> ());";
+
+ if (versioned)
+ os << "const schema_version_migration& svm (" <<
+ "sts.version_migration (" << schema_name << "));";
+
+ os << endl;
// Rebind the image if necessary.
//
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index d4bc7a8..ac81bdf 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -4820,8 +4820,8 @@ namespace relational
if (s.versioned || s.versioned_containers)
os << "const schema_version_migration& svm (" << endl
- << "esc." << m.name () << ".connection ().database ()." <<
- "schema_version_migration (" << schema_name << "));"
+ << "esc." << m.name () << ".version_migration (" <<
+ schema_name << "));"
<< endl;
// Load values, if any.
@@ -5097,8 +5097,8 @@ namespace relational
if (s.versioned || s.readwrite_versioned_containers)
os << "const schema_version_migration& svm (" << endl
- << "esc." << m.name () << ".connection ().database ()." <<
- "schema_version_migration (" << schema_name << "));"
+ << "esc." << m.name () << ".version_migration (" <<
+ schema_name << "));"
<< endl;
// Update values, if any.