summaryrefslogtreecommitdiff
path: root/odb-tests/common/composite
diff options
context:
space:
mode:
Diffstat (limited to 'odb-tests/common/composite')
-rw-r--r--odb-tests/common/composite/buildfile41
-rw-r--r--odb-tests/common/composite/driver.cxx229
-rw-r--r--odb-tests/common/composite/test.hxx250
-rw-r--r--odb-tests/common/composite/testscript53
4 files changed, 573 insertions, 0 deletions
diff --git a/odb-tests/common/composite/buildfile b/odb-tests/common/composite/buildfile
new file mode 100644
index 0000000..0a60638
--- /dev/null
+++ b/odb-tests/common/composite/buildfile
@@ -0,0 +1,41 @@
+# file : common/composite/buildfile
+# license : GNU GPL v2; see accompanying LICENSE file
+
+import libodb = libodb%lib{odb}
+
+libs =
+
+for db: $databases
+ import libs += libodb-$db%lib{odb-$db}
+
+import libs += lib{common}
+
+exe{driver}: {hxx cxx}{* -*-odb -*-odb-*} {hxx ixx cxx}{test-odb} testscript
+
+# Introduce the metadata library target to make sure the libodb library is
+# resolved for the odb_compile ad hoc rule (see build/root.build for details).
+#
+libue{test-meta}: $libodb
+
+<{hxx ixx cxx}{test-odb}>: hxx{test} libue{test-meta}
+
+for db: $databases
+{
+ exe{driver}: {hxx ixx cxx}{test-odb-$db}: include = $multi
+ <{hxx ixx cxx}{test-odb-$db}>: hxx{test} libue{test-meta}
+}
+
+exe{driver}: libue{test-meta} $libs
+
+# Specify the ODB custom options to be used by the odb_compile ad hoc rule
+# (see build/root.build for details).
+#
+odb_options = --table-prefix t_comp_ \
+ --generate-schema \
+ --generate-query
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Testscript's run-time prerequisites.
+#
+exe{driver}: ../../alias{database-client}: include = adhoc
diff --git a/odb-tests/common/composite/driver.cxx b/odb-tests/common/composite/driver.cxx
new file mode 100644
index 0000000..06b24b2
--- /dev/null
+++ b/odb-tests/common/composite/driver.cxx
@@ -0,0 +1,229 @@
+// file : common/composite/driver.cxx
+// license : GNU GPL v2; see accompanying LICENSE file
+
+// Test composite value types.
+//
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include <odb/database.hxx>
+#include <odb/transaction.hxx>
+
+#include <libcommon/common.hxx>
+
+#include "test.hxx"
+#include "test-odb.hxx"
+
+using namespace std;
+using namespace odb::core;
+
+#undef NDEBUG
+#include <cassert>
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ unique_ptr<database> db (create_database (argc, argv));
+
+ // Test basic composite functionality.
+ //
+ for (unsigned short i (0); i < 2; ++i)
+ {
+ using namespace test1;
+
+ person p (1);
+ p.name_.first = "Joe";
+ p.name_.last = "Dirt";
+ p.name_.title = "Mr";
+ p.name_.alias.first = "Anthony";
+ p.name_.alias.last = "Clean";
+ p.name_.nick = "Squeaky";
+ p.name_.flags.nick = true;
+ p.name_.flags.alias = false;
+ p.age_ = 32;
+
+ // persist
+ //
+ {
+ transaction t (db->begin ());
+ db->persist (p);
+ t.commit ();
+ }
+
+ // load & check
+ //
+ {
+ transaction t (db->begin ());
+ unique_ptr<person> p1 (db->load<person> (1));
+ t.commit ();
+
+ assert (p == *p1);
+ }
+
+ p.name_.title = "Mrs";
+ p.name_.alias.first = "Anthonia";
+ p.name_.flags.nick = false;
+ p.name_.flags.alias = true;
+
+ // update
+ //
+ {
+ transaction t (db->begin ());
+ db->update (p);
+ t.commit ();
+ }
+
+ // load & check
+ //
+ {
+ transaction t (db->begin ());
+ unique_ptr<person> p1 (db->load<person> (1));
+ t.commit ();
+
+ assert (p == *p1);
+ }
+
+ typedef odb::query<person> query;
+ typedef odb::result<person> result;
+
+ // query
+ //
+ {
+ transaction t (db->begin ());
+
+ result r (db->query<person> (query::name.first == "Joe"));
+
+ assert (!r.empty ());
+ assert (*r.begin () == p);
+ assert (size (r) == 1);
+
+ t.commit ();
+ }
+
+ // query
+ //
+ {
+ transaction t (db->begin ());
+
+ result r (db->query<person> (query::name.flags.alias));
+
+ assert (!r.empty ());
+ assert (*r.begin () == p);
+ assert (size (r) == 1);
+
+ t.commit ();
+ }
+
+ // erase
+ //
+ if (i == 0)
+ {
+ transaction t (db->begin ());
+ db->erase<person> (1);
+ t.commit ();
+ }
+ }
+
+ // Test composite class template instantiation.
+ //
+ {
+ using namespace test2;
+
+ object o (1);
+
+ o.comp_.num = 123;
+ o.comp_.str = "abc";
+ o.comp_.vec.push_back (int_str_pair (123, "abc"));
+ o.comp_.vec.push_back (int_str_pair (234, "bcd"));
+ o.comp_.vec.push_back (int_str_pair (345, "cde"));
+
+ o.pair_.first = 123;
+ o.pair_.second = "abc";
+
+ o.vec_.push_back (int_str_pair (123, "abc"));
+ o.vec_.push_back (int_str_pair (234, "bcd"));
+ o.vec_.push_back (int_str_pair (345, "cde"));
+
+ // persist
+ //
+ {
+ transaction t (db->begin ());
+ db->persist (o);
+ t.commit ();
+ }
+
+ // load & check
+ //
+ {
+ transaction t (db->begin ());
+ unique_ptr<object> o1 (db->load<object> (1));
+ t.commit ();
+
+ assert (o == *o1);
+ }
+ }
+
+ // Test empty column name.
+ //
+ {
+ using namespace test3;
+
+ object o (1);
+ o.c_.str = "abc";
+
+ // persist
+ //
+ {
+ transaction t (db->begin ());
+ db->persist (o);
+ t.commit ();
+ }
+
+ // load & check
+ //
+ {
+ transaction t (db->begin ());
+ unique_ptr<object> o1 (db->load<object> (1));
+ t.commit ();
+
+ assert (o == *o1);
+ }
+ }
+
+ // Test composite definition inside object.
+ {
+ using namespace test4;
+
+ object o (1);
+ o.str ("abc");
+ o.x (123);
+ o.y (234);
+
+ // persist
+ //
+ {
+ transaction t (db->begin ());
+ db->persist (o);
+ t.commit ();
+ }
+
+ // load & check
+ //
+ {
+ transaction t (db->begin ());
+ unique_ptr<object> o1 (db->load<object> (1));
+ t.commit ();
+
+ assert (o == *o1);
+ }
+ }
+ }
+ catch (const odb::exception& e)
+ {
+ cerr << e.what () << endl;
+ return 1;
+ }
+}
diff --git a/odb-tests/common/composite/test.hxx b/odb-tests/common/composite/test.hxx
new file mode 100644
index 0000000..13b2025
--- /dev/null
+++ b/odb-tests/common/composite/test.hxx
@@ -0,0 +1,250 @@
+// file : common/composite/test.hxx
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef TEST_HXX
+#define TEST_HXX
+
+#include <string>
+#include <vector>
+#include <utility> // std::pair
+
+#include <odb/core.hxx>
+
+// Test basic composite functionality.
+//
+#pragma db namespace table("t1_")
+namespace test1
+{
+ #pragma db value
+ struct name
+ {
+ std::string first;
+ std::string last;
+ };
+
+ #pragma db value
+ struct name_title
+ {
+ std::string title;
+ };
+
+ #pragma db value
+ struct name_title_ex: name_title
+ {
+ // Test value types without data members.
+ };
+
+ #pragma db value
+ struct name_flags
+ {
+ bool nick;
+ bool alias;
+ };
+
+ #pragma db value
+ struct name_ex: name, name_title_ex
+ {
+ name alias;
+ std::string nick;
+
+ #pragma db column("show_")
+ name_flags flags;
+ };
+
+ #pragma db object
+ struct person
+ {
+ person () {}
+ person (unsigned long id): id_ (id) {}
+
+ #pragma db id
+ unsigned long id_;
+
+ #pragma db column("")
+ name_ex name_;
+
+ unsigned short age_;
+ };
+
+ inline bool
+ operator== (const person& x, const person& y)
+ {
+ return x.id_ == y.id_ &&
+ x.name_.first == y.name_.first&&
+ x.name_.last == y.name_.last &&
+ x.name_.title == y.name_.title &&
+ x.name_.alias.first == y.name_.alias.first &&
+ x.name_.alias.last == y.name_.alias.last &&
+ x.name_.nick == y.name_.nick &&
+ x.name_.flags.nick == y.name_.flags.nick &&
+ x.name_.flags.alias == y.name_.flags.alias &&
+ x.age_ == y.age_;
+ }
+}
+
+// Test composite class template instantiation.
+//
+#pragma db namespace table("t2_")
+namespace test2
+{
+ template <typename I, typename S>
+ struct comp
+ {
+ I num;
+ S str;
+ std::vector<std::pair<I, S> > vec;
+ };
+
+ template <typename I, typename S>
+ inline bool
+ operator== (const comp<I, S>& x, const comp<I, S>& y)
+ {
+ return x.num == y.num && x.str == y.str && x.vec == y.vec;
+ }
+
+ typedef std::pair<int, std::string> int_str_pair;
+ #pragma db value(int_str_pair)
+
+ // Make sure we use the name that was specified in the pragma.
+ //
+#ifdef ODB_COMPILER
+ typedef comp<int, std::string> int_str_comp1;
+#endif
+
+ typedef comp<int, std::string> int_str_comp;
+ #pragma db value(int_str_comp)
+
+ #pragma db object
+ struct object
+ {
+ object () {}
+ object (unsigned long id): id_ (id) {}
+
+ #pragma db id
+ unsigned long id_;
+
+ comp<int, std::string> comp_;
+ std::pair<int, std::string> pair_;
+ std::vector<int_str_pair> vec_;
+ };
+
+ inline bool
+ operator== (const object& x, const object& y)
+ {
+ return x.id_ == y.id_ &&
+ x.comp_ == y.comp_ &&
+ x.pair_ == y.pair_ &&
+ x.vec_ == y.vec_;
+ }
+}
+
+// Test empty column name.
+//
+#pragma db namespace table("t3_")
+namespace test3
+{
+ #pragma db value
+ struct comp
+ {
+ #pragma db column("")
+ std::string str;
+ };
+
+ #pragma db object
+ struct object
+ {
+ object () {}
+ object (unsigned long id): id_ (id) {}
+
+ #pragma db id
+ unsigned long id_;
+
+ comp c_;
+ };
+
+ inline bool
+ operator== (const object& x, const object& y)
+ {
+ return x.id_ == y.id_ && x.c_.str == y.c_.str;
+ }
+}
+
+// Test composite definition inside object.
+//
+#pragma db namespace table("t4_")
+namespace test4
+{
+ #pragma db object
+ struct object
+ {
+ object (unsigned long id = 0): id_ (id) {}
+
+ unsigned long id () const {return id_;}
+
+ void str (const std::string& s) {c_.str = s;}
+ const std::string& str () const {return c_.str;}
+
+ void x (int i) {p_.first = i;}
+ int x () const {return p_.first;}
+
+ void y (int i) {p_.second = i;}
+ int y () const {return p_.second;}
+
+ private:
+ friend class odb::access;
+
+ #pragma db id
+ unsigned long id_;
+
+ #pragma db value
+ struct comp
+ {
+ std::string str;
+ };
+
+ comp c_;
+
+ typedef std::pair<int, int> int_pair;
+ #pragma db value(int_pair)
+
+ int_pair p_;
+ };
+
+ inline bool
+ operator== (const object& x, const object& y)
+ {
+ return x.id () == y.id () && x.str () == y.str () &&
+ x.x () == y.x () && x.y () == y.y ();
+ }
+}
+
+// Test composite name clashes in query columns (compilation test)
+//
+#pragma db namespace table("t5_")
+namespace test5
+{
+ // Class-member conflict.
+ //
+ #pragma db value
+ struct value {int value_;};
+
+ // Class-class conflict.
+ //
+ #pragma db value
+ struct inner {int value;};
+
+ #pragma db value
+ struct outer {inner value;};
+
+ #pragma db object
+ struct object
+ {
+ #pragma db id
+ int id;
+
+ outer value;
+ test5::value v;
+ };
+}
+
+#endif // TEST_HXX
diff --git a/odb-tests/common/composite/testscript b/odb-tests/common/composite/testscript
new file mode 100644
index 0000000..f890985
--- /dev/null
+++ b/odb-tests/common/composite/testscript
@@ -0,0 +1,53 @@
+# file : common/composite/testscript
+# license : GNU GPL v2; see accompanying LICENSE file
+
+.include ../../database-options.testscript
+
+: mysql
+:
+if $mysql
+{
+ .include ../../mysql.testscript
+
+ $create_schema;
+ $*
+}
+
+: sqlite
+:
+if $sqlite
+{
+ .include ../../sqlite.testscript
+
+ $*
+}
+
+: pgsql
+:
+if $pgsql
+{
+ .include ../../pgsql.testscript
+
+ $create_schema;
+ $*
+}
+
+: oracle
+:
+if $oracle
+{
+ .include ../../oracle.testscript
+
+ $create_schema;
+ $*
+}
+
+: mssql
+:
+if $mssql
+{
+ .include ../../mssql.testscript
+
+ $create_schema;
+ $*
+}