diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-26 10:58:50 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-26 10:58:50 +0200 |
commit | 3d022058bc8b61c14c2d16e760ea1393d775c0d0 (patch) | |
tree | 81e7dd01fc15220b96c39c406df7bb5ad45627e0 | |
parent | d7752cdb86957f7dc0caffe6033e872443ad8153 (diff) |
Reimplement image copying for Oracle
Now we no longer "steal" descriptors (destructive copy). Instead, for
LOBs, we clone the locator using OCILobAssign(). For date-time types we
extract the data during copying. As a result of this change we no longer
need to track image changes and rebind the statements.
-rw-r--r-- | oracle/types/driver.cxx | 71 | ||||
-rw-r--r-- | oracle/types/test.hxx | 28 |
2 files changed, 78 insertions, 21 deletions
diff --git a/oracle/types/driver.cxx b/oracle/types/driver.cxx index ab7ae24..4b40bd1 100644 --- a/oracle/types/driver.cxx +++ b/oracle/types/driver.cxx @@ -180,8 +180,23 @@ main (int argc, char* argv[]) // Test large BLOBs. // - blob b1 (1, 50000); - blob b2 (2, 500000); + descriptor b1 (1); + b1.blob.assign (50000, 'b'); + b1.timestamp = date_time (1996, 3, 9, 18, 2, 54, 123000); + b1.interval_ds = time_interval (0, 0, 13, 15, 23, 19, 123000); + b1.interval_ym = time_interval (12, 3, 0, 0, 0, 0, 0); + + descriptor b2 (2); + b2.blob.assign (500000, 'b'); + b2.timestamp = date_time (1997, 4, 10, 19, 3, 55, 234000); + b2.interval_ds = time_interval (0, 0, 14, 16, 24, 20, 234000); + b2.interval_ym = time_interval (13, 4, 0, 0, 0, 0, 0); + + descriptor b3 (3); + b3.blob.assign (5000, 'b'); + b3.timestamp = date_time (1995, 2, 8, 17, 1, 53, 120000); + b3.interval_ds = time_interval (0, 0, 12, 14, 22, 18, 120000); + b3.interval_ym = time_interval (11, 2, 0, 0, 0, 0, 0); // Persist. // @@ -196,40 +211,74 @@ main (int argc, char* argv[]) // { transaction t (db->begin ()); - auto_ptr<blob> p1 (db->load<blob> (1)); - auto_ptr<blob> p2 (db->load<blob> (2)); + auto_ptr<descriptor> p1 (db->load<descriptor> (1)); + auto_ptr<descriptor> p2 (db->load<descriptor> (2)); t.commit (); assert (b1 == *p1); assert (b2 == *p2); } - // Test image copying with LOB data. + // Test image copying with descriptor-based type (LOB, date-time) data. // { - typedef oracle::query<blob> query; - typedef odb::result<blob> result; + typedef oracle::query<descriptor> query; + typedef odb::result<descriptor> result; transaction t (db->begin ()); - result r (db->query<blob> (query::id < 3)); + // Pre-bind the image for other operations. + // + { + db->persist (b3); + db->update (b3); + db->reload (b3); + db->erase (b3); + } + + + result r (db->query<descriptor> (query::id < 3)); result::iterator i (r.begin ()); assert (i != r.end ()); + + { + result r (db->query<descriptor> (query::id > 1)); + result::iterator i (r.begin ()); + assert (i != r.end ()); + assert (*i == b2); + assert (++i == r.end ()); + } + + assert (*i == b1); // Load from copy (copy c-tor). + ++i; assert (i != r.end ()); { - result r (db->query<blob> (query::id < 2)); + result r (db->query<descriptor> (query::id < 2)); result::iterator i (r.begin ()); assert (i != r.end ()); - assert (i->value_.size () == 50000); + assert (*i == b1); assert (++i == r.end ()); } - assert (i->value_.size () == 500000); // Load from copy. + assert (*i == b2); // Load from copy (copy assign). assert (++i == r.end ()); + // Make sure all other operations are still working. + // + { + db->persist (b3); + auto_ptr<descriptor> p (db->load<descriptor> (3)); + assert (b3 == *p); + b3.blob.push_back (123); + db->update (b3); + db->reload (p); + assert (b3 == *p); + db->erase (b3); + } + t.commit (); } diff --git a/oracle/types/test.hxx b/oracle/types/test.hxx index a3dac3f..ac903b8 100644 --- a/oracle/types/test.hxx +++ b/oracle/types/test.hxx @@ -275,25 +275,33 @@ struct big_int }; #pragma db object -struct blob +struct descriptor { - blob (): id_ (0) {} - - blob (unsigned int id, std::size_t n) - : id_ (id), value_ (n, 'b') - { - } + descriptor (unsigned int id = 0): id_ (id) {} #pragma db id unsigned int id_; #pragma db type ("BLOB") - std::vector<char> value_; + std::vector<char> blob; + + #pragma db type ("TIMESTAMP(6)") + date_time timestamp; + + #pragma db type ("INTERVAL DAY TO SECOND") + time_interval interval_ds; + + #pragma db type ("INTERVAL YEAR TO MONTH") + time_interval interval_ym; bool - operator== (const blob& y) const + operator== (const descriptor& y) const { - return id_ == y.id_ && value_ == y.value_; + return id_ == y.id_ && + blob == y.blob && + timestamp == y.timestamp && + interval_ds == y.interval_ds && + interval_ym == y.interval_ym; } }; |