aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-11-26 10:58:50 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-26 10:58:50 +0200
commit3d022058bc8b61c14c2d16e760ea1393d775c0d0 (patch)
tree81e7dd01fc15220b96c39c406df7bb5ad45627e0
parentd7752cdb86957f7dc0caffe6033e872443ad8153 (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.cxx71
-rw-r--r--oracle/types/test.hxx28
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;
}
};