summaryrefslogtreecommitdiff
path: root/odb/relational/oracle
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational/oracle')
-rw-r--r--odb/relational/oracle/common.cxx522
-rw-r--r--odb/relational/oracle/common.hxx203
-rw-r--r--odb/relational/oracle/context.cxx795
-rw-r--r--odb/relational/oracle/context.hxx188
-rw-r--r--odb/relational/oracle/header.cxx230
-rw-r--r--odb/relational/oracle/inline.cxx42
-rw-r--r--odb/relational/oracle/model.cxx64
-rw-r--r--odb/relational/oracle/schema.cxx696
-rw-r--r--odb/relational/oracle/source.cxx646
9 files changed, 0 insertions, 3386 deletions
diff --git a/odb/relational/oracle/common.cxx b/odb/relational/oracle/common.cxx
deleted file mode 100644
index 7caafc9..0000000
--- a/odb/relational/oracle/common.cxx
+++ /dev/null
@@ -1,522 +0,0 @@
-// file : odb/relational/oracle/common.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <cassert>
-
-#include <odb/relational/oracle/common.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace oracle
- {
- //
- // member_base
- //
-
- sql_type const& member_base::
- member_sql_type (semantics::data_member& m)
- {
- return parse_sql_type (column_type (m, key_prefix_), m);
- }
-
- void member_base::
- traverse_simple (member_info& mi)
- {
- switch (mi.st->type)
- {
- // Numeric types.
- //
- case sql_type::NUMBER:
- {
- const sql_type& st (*mi.st);
-
- if (st.prec)
- {
- unsigned short r (st.prec_value);
-
- if (!st.scale)
- {
- if (r <= 10)
- traverse_int32 (mi);
- // Only OCI versions 11.2 and later support insertion and
- // extraction into a 64 bit integer.
- //
- else if (
- (options.oracle_client_version () >= oracle_version (11, 2)) &&
- (r <= 19 || (r == 20 && unsigned_integer (mi.t))))
- traverse_int64 (mi);
- else
- traverse_big_int (mi);
- }
- else
- {
- // We can calculate the decimal exponent of the normalised
- // floating point equivalent of the fixed point number using
- // e = p - s, where p is the precision, s is the scale, and
- // e the exponent. We can then use this to determine whether
- // or not a value of Oracle SQL type NUMBER can be completely
- // stored in the native floating point type.
- //
-
- // The maximum decimal precision of a float is 7 significant
- // digits. The minimum and maximum decimal exponents
- // representable by a float are -37 and 38 respectively.
- //
- if (r <= 7)
- {
- int e = r - st.scale_value;
-
- if (e >= -37 && e <= 38)
- traverse_float (mi);
- else
- traverse_double (mi);
- }
-
- // The maximum decimal precision of a double is 15 significant
- // digits. The minimum and maximum decimal exponent representable
- // by a double exceeds that of the Oracle NUMBER type.
- //
- else if (r <= 15)
- traverse_double (mi);
- else
- traverse_big_float (mi);
- }
- }
- else
- // If there is no precision, then this is a floating-point number.
- //
- traverse_double (mi);
-
- break;
- }
- case sql_type::FLOAT:
- {
- // We map FLOAT types based exclusively on their binary precision
- // seeing that in 99% of cases it is the precision that is the
- // limiting factor and not the exponent.
- //
- if (mi.st->prec_value <= 24)
- traverse_float (mi);
- else if (mi.st->prec_value <= 53)
- traverse_double (mi);
- else
- traverse_big_float (mi);
-
- break;
- }
- case sql_type::BINARY_FLOAT:
- {
- traverse_float (mi);
- break;
- }
- case sql_type::BINARY_DOUBLE:
- {
- traverse_double (mi);
- break;
- }
- // Data-time types.
- //
- case sql_type::DATE:
- {
- traverse_date (mi);
- break;
- }
- case sql_type::TIMESTAMP:
- {
- traverse_timestamp (mi);
- break;
- }
- case sql_type::INTERVAL_YM:
- {
- traverse_interval_ym (mi);
- break;
- }
- case sql_type::INTERVAL_DS:
- {
- traverse_interval_ds (mi);
- break;
- }
- // String and binary types.
- //
- case sql_type::CHAR:
- case sql_type::NCHAR:
- case sql_type::VARCHAR2:
- case sql_type::NVARCHAR2:
- case sql_type::RAW:
- {
- traverse_string (mi);
- break;
- }
- case sql_type::BLOB:
- case sql_type::CLOB:
- case sql_type::NCLOB:
- {
- traverse_lob (mi);
- break;
- }
- case sql_type::invalid:
- {
- assert (false);
- break;
- }
- }
- }
-
- //
- // member_image_type
- //
-
- member_image_type::
- member_image_type (base const& x)
- : member_base::base (x), // virtual base
- base (x) {}
-
- member_image_type::
- member_image_type ()
- : relational::member_base (0, 0, string (), string ()) {}
-
- member_image_type::
- member_image_type (semantics::type* type,
- const custom_cxx_type* ct,
- string const& fq_type,
- string const& key_prefix)
- : relational::member_base (type, ct, fq_type, key_prefix) {}
-
- string member_image_type::
- image_type (semantics::data_member& m)
- {
- type_.clear ();
- member_base::traverse (m, true);
- return type_;
- }
-
- void member_image_type::
- traverse_composite (member_info& mi)
- {
- type_ = "composite_value_traits< " + mi.fq_type () +
- ", id_oracle >::image_type";
- }
-
- void member_image_type::
- traverse_int32 (member_info& mi)
- {
- if (unsigned_integer (mi.t))
- type_ = "unsigned int";
- else
- type_ = "int";
- }
-
- void member_image_type::
- traverse_int64 (member_info& mi)
- {
- if (unsigned_integer (mi.t))
- type_ = "unsigned long long";
- else
- type_ = "long long";
- }
-
- void member_image_type::
- traverse_big_int (member_info&)
- {
- type_ = "char*";
- }
-
- void member_image_type::
- traverse_float (member_info&)
- {
- type_ = "float";
- }
-
- void member_image_type::
- traverse_double (member_info&)
- {
- type_ = "double";
- }
-
- void member_image_type::
- traverse_big_float (member_info&)
- {
- type_ = "char*";
- }
-
- void member_image_type::
- traverse_date (member_info&)
- {
- type_ = "char*";
- }
-
- void member_image_type::
- traverse_timestamp (member_info&)
- {
- type_ = "oracle::datetime";
- }
-
- void member_image_type::
- traverse_interval_ym (member_info&)
- {
- type_ = "oracle::interval_ym";
- }
-
- void member_image_type::
- traverse_interval_ds (member_info&)
- {
- type_ = "oracle::interval_ds";
- }
-
- void member_image_type::
- traverse_string (member_info&)
- {
- type_ = "char*";
- }
-
- void member_image_type::
- traverse_lob (member_info&)
- {
- type_ = "oracle::lob_callback";
- }
-
- entry<member_image_type> member_image_type_;
-
- //
- // member_database_type
- //
-
- namespace
- {
- const char* string_bin_database_id[] =
- {
- "id_string", // CHAR
- "id_nstring", // NCHAR
- "id_string", // VARCHAR2
- "id_nstring", // NVARCHAR2
- "id_raw" // RAW
- };
-
- const char* lob_database_id[] =
- {
- "id_blob",
- "id_clob",
- "id_nclob"
- };
- }
-
- member_database_type_id::
- member_database_type_id (base const& x)
- : member_base::base (x), // virtual base
- base (x) {}
-
- member_database_type_id::
- member_database_type_id ()
- : member_base::base (0, 0, string (), string ()), // virtual base
- base (0, 0, string (), string ()) {}
-
- member_database_type_id::
- member_database_type_id (semantics::type* type,
- const custom_cxx_type* ct,
- string const& fq_type,
- string const& key_prefix)
- : member_base::base (type, ct, fq_type, key_prefix), // virtual base
- base (type, ct, fq_type, key_prefix) {}
-
- string member_database_type_id::
- database_type_id (type& m)
- {
- type_id_.clear ();
- member_base::traverse (m, true);
- return type_id_;
- }
-
- void member_database_type_id::
- traverse_composite (member_info&)
- {
- assert (false);
- }
-
- void member_database_type_id::
- traverse_int32 (member_info&)
- {
- type_id_ = "oracle::id_int32";
- }
-
- void member_database_type_id::
- traverse_int64 (member_info&)
- {
- type_id_ = "oracle::id_int64";
- }
-
- void member_database_type_id::
- traverse_big_int (member_info&)
- {
- type_id_ = "oracle::id_big_int";
- }
-
- void member_database_type_id::
- traverse_float (member_info&)
- {
- type_id_ = "oracle::id_float";
- }
-
- void member_database_type_id::
- traverse_double (member_info&)
- {
- type_id_ = "oracle::id_double";
- }
-
- void member_database_type_id::
- traverse_big_float (member_info&)
- {
- type_id_ = "oracle::id_big_float";
- }
-
- void member_database_type_id::
- traverse_date (member_info&)
- {
- type_id_ = "oracle::id_date";
- }
-
- void member_database_type_id::
- traverse_timestamp (member_info&)
- {
- type_id_ = "oracle::id_timestamp";
- }
-
- void member_database_type_id::
- traverse_interval_ym (member_info&)
- {
- type_id_ = "oracle::id_interval_ym";
- }
-
- void member_database_type_id::
- traverse_interval_ds (member_info&)
- {
- type_id_ = "oracle::id_interval_ds";
- }
-
- void member_database_type_id::
- traverse_string (member_info& mi)
- {
- type_id_ = string ("oracle::") +
- string_bin_database_id[mi.st->type - sql_type::CHAR];
- }
-
- void member_database_type_id::
- traverse_lob (member_info& mi)
- {
- type_id_ = string ("oracle::") +
- lob_database_id[mi.st->type - sql_type::BLOB];
- }
-
- entry<member_database_type_id> member_database_type_id_;
-
- //
- // query_columns
- //
-
- struct query_columns: relational::query_columns, context
- {
- query_columns (base const& x): base_impl (x) {}
-
- void
- column_ctor (string const& type, string const& name, string const& base)
- {
- os << name << " (";
-
- if (multi_dynamic)
- os << "odb::query_column< " << type << " >& qc," << endl;
-
- os << "const char* t," << endl
- << "const char* c," << endl
- << "const char* conv," << endl
- << "unsigned short p = 0xFFF," << endl
- << "short s = 0xFFF)" << endl
- << " : " << base << " (" << (multi_dynamic ? "qc, " : "") <<
- "t, c, conv, p, s)"
- << "{"
- << "}";
- }
-
- virtual void
- column_ctor_args_extra (semantics::data_member& m)
- {
- // For some types we need to pass precision and scale.
- //
- sql_type const& st (parse_sql_type (column_type (), m));
-
- switch (st.type)
- {
- case sql_type::NUMBER:
- {
- if (st.prec)
- {
- os << ", " << st.prec_value;
-
- if (st.scale)
- os << ", " << st.scale_value;
- }
- break;
- }
- case sql_type::FLOAT:
- {
- os << ", " << st.prec_value;
- break;
- }
- case sql_type::TIMESTAMP:
- {
- os << ", " << st.prec_value;
- break;
- }
- case sql_type::INTERVAL_YM:
- {
- os << ", " << st.prec_value;
- break;
- }
- case sql_type::INTERVAL_DS:
- {
- // INTERVAL DAY TO SECOND has two precisions.
- //
- os << ", " << st.prec_value << ", " << st.scale_value;
- break;
- }
- case sql_type::CHAR:
- case sql_type::NCHAR:
- case sql_type::VARCHAR2:
- case sql_type::NVARCHAR2:
- case sql_type::RAW:
- {
- // The same logic as in header.cxx.
- //
- size_t n (st.prec ? st.prec_value : 1);
-
- if (!st.byte_semantics)
- n *= 4;
-
- if (st.type == sql_type::VARCHAR2 ||
- st.type == sql_type::NVARCHAR2)
- n = n > 4000 ? 4000 : n;
- else
- n = n > 2000 ? 2000 : n;
-
- os << ", " << n;
- break;
- }
- default:
- {
- break;
- }
- }
- }
-
- virtual string
- database_type_id (semantics::data_member& m)
- {
- return member_database_type_id_.database_type_id (m);
- }
-
- private:
- member_database_type_id member_database_type_id_;
- };
- entry<query_columns> query_columns_;
- }
-}
diff --git a/odb/relational/oracle/common.hxx b/odb/relational/oracle/common.hxx
deleted file mode 100644
index 1958aab..0000000
--- a/odb/relational/oracle/common.hxx
+++ /dev/null
@@ -1,203 +0,0 @@
-// file : odb/relational/oracle/common.hxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_RELATIONAL_ORACLE_COMMON_HXX
-#define ODB_RELATIONAL_ORACLE_COMMON_HXX
-
-#include <odb/relational/common.hxx>
-#include <odb/relational/oracle/context.hxx>
-
-namespace relational
-{
- namespace oracle
- {
- struct member_base: virtual relational::member_base_impl<sql_type>, context
- {
- member_base (base const& x): base (x), base_impl (x) {}
-
- // This c-tor is for the direct use inside the oracle namespace.
- // If you do use this c-tor, you should also explicitly call
- // relational::member_base (aka base).
- //
- member_base () {}
-
- virtual sql_type const&
- member_sql_type (semantics::data_member&);
-
- virtual void
- traverse_simple (member_info&);
-
- virtual void
- traverse_int32 (member_info&)
- {
- }
-
- virtual void
- traverse_int64 (member_info&)
- {
- }
-
- virtual void
- traverse_big_int (member_info&)
- {
- }
-
- virtual void
- traverse_float (member_info&)
- {
- }
-
- virtual void
- traverse_double (member_info&)
- {
- }
-
- virtual void
- traverse_big_float (member_info&)
- {
- }
-
- virtual void
- traverse_date (member_info&)
- {
- }
-
- virtual void
- traverse_timestamp (member_info&)
- {
- }
-
- virtual void
- traverse_interval_ym (member_info&)
- {
- }
-
- virtual void
- traverse_interval_ds (member_info&)
- {
- }
-
- virtual void
- traverse_string (member_info&)
- {
- }
-
- virtual void
- traverse_lob (member_info&)
- {
- }
- };
-
- struct member_image_type: relational::member_image_type,
- member_base
- {
- member_image_type (base const&);
- member_image_type ();
- member_image_type (semantics::type* type,
- const custom_cxx_type*,
- string const& fq_type = string (),
- string const& key_prefix = string ());
- virtual string
- image_type (semantics::data_member&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_int32 (member_info&);
-
- virtual void
- traverse_int64 (member_info&);
-
- virtual void
- traverse_big_int (member_info&);
-
- virtual void
- traverse_float (member_info&);
-
- virtual void
- traverse_double (member_info&);
-
- virtual void
- traverse_big_float (member_info&);
-
- virtual void
- traverse_date (member_info&);
-
- virtual void
- traverse_timestamp (member_info&);
-
- virtual void
- traverse_interval_ym (member_info&);
-
- virtual void
- traverse_interval_ds (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_lob (member_info&);
-
- private:
- string type_;
- };
-
- struct member_database_type_id: relational::member_database_type_id,
- member_base
- {
- member_database_type_id (base const&);
- member_database_type_id ();
- member_database_type_id (semantics::type* type,
- const custom_cxx_type*,
- string const& fq_type = string (),
- string const& key_prefix = string ());
-
- virtual string
- database_type_id (type&);
-
- virtual void
- traverse_composite (member_info&);
-
- virtual void
- traverse_int32 (member_info&);
-
- virtual void
- traverse_int64 (member_info&);
-
- virtual void
- traverse_big_int (member_info&);
-
- virtual void
- traverse_float (member_info&);
-
- virtual void
- traverse_double (member_info&);
-
- virtual void
- traverse_big_float (member_info&);
-
- virtual void
- traverse_date (member_info&);
-
- virtual void
- traverse_timestamp (member_info&);
-
- virtual void
- traverse_interval_ym (member_info&);
-
- virtual void
- traverse_interval_ds (member_info&);
-
- virtual void
- traverse_string (member_info&);
-
- virtual void
- traverse_lob (member_info&);
-
- private:
- string type_id_;
- };
- }
-}
-#endif // ODB_RELATIONAL_ORACLE_COMMON_HXX
diff --git a/odb/relational/oracle/context.cxx b/odb/relational/oracle/context.cxx
deleted file mode 100644
index 12ce0aa..0000000
--- a/odb/relational/oracle/context.cxx
+++ /dev/null
@@ -1,795 +0,0 @@
-// file : odb/relational/oracle/context.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <cassert>
-#include <sstream>
-
-#include <odb/sql-token.hxx>
-#include <odb/sql-lexer.hxx>
-
-#include <odb/relational/oracle/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace oracle
- {
- namespace
- {
- struct type_map_entry
- {
- char const* const cxx_type;
- char const* const db_type;
- char const* const db_id_type;
- bool const null;
- };
-
- type_map_entry type_map[] =
- {
- {"bool", "NUMBER(1)", 0, false},
-
- {"char", "CHAR(1)", 0, false},
- {"signed char", "NUMBER(3)", 0, false},
- {"unsigned char", "NUMBER(3)", 0, false},
-
- {"short int", "NUMBER(5)", 0, false},
- {"short unsigned int", "NUMBER(5)", 0, false},
-
- {"int", "NUMBER(10)", 0, false},
- {"unsigned int", "NUMBER(10)", 0, false},
-
- {"long int", "NUMBER(19)", 0, false},
- {"long unsigned int", "NUMBER(20)", 0, false},
-
- {"long long int", "NUMBER(19)", 0, false},
- {"long long unsigned int", "NUMBER(20)", 0, false},
-
- {"float", "BINARY_FLOAT", 0, false},
- {"double", "BINARY_DOUBLE", 0, false},
-
- // Oracle treats empty VARCHAR2 (and NVARCHAR2) strings as NULL.
- //
- {"::std::string", "VARCHAR2(512)", 0, true},
-
- {"::size_t", "NUMBER(20)", 0, false},
- {"::std::size_t", "NUMBER(20)", 0, false}
- };
- }
-
- context* context::current_;
-
- context::
- ~context ()
- {
- if (current_ == this)
- current_ = 0;
- }
-
- context::
- context (ostream& os,
- semantics::unit& u,
- options_type const& ops,
- features_type& f,
- sema_rel::model* m)
- : root_context (os, u, ops, f, data_ptr (new (shared) data (os))),
- base_context (static_cast<data*> (root_context::data_.get ()), m),
- data_ (static_cast<data*> (base_context::data_))
- {
- assert (current_ == 0);
- current_ = this;
-
- generate_grow = false;
- need_alias_as = false;
- insert_send_auto_id = false;
- delay_freeing_statement_result = false;
- need_image_clone = true;
- generate_bulk = true;
- global_index = true;
- global_fkey = true;
- data_->bind_vector_ = "oracle::bind*";
-
- // Populate the C++ type to DB type map.
- //
- for (size_t i (0); i < sizeof (type_map) / sizeof (type_map_entry); ++i)
- {
- type_map_entry const& e (type_map[i]);
-
- type_map_type::value_type v (
- e.cxx_type,
- db_type_type (
- e.db_type, e.db_id_type ? e.db_id_type : e.db_type, e.null));
-
- data_->type_map_.insert (v);
- }
- }
-
- context::
- context ()
- : data_ (current ().data_)
- {
- }
-
- string const& context::
- convert_expr (string const& sqlt, semantics::data_member& m, bool to)
- {
- sql_type const& t (parse_sql_type (sqlt, m));
- return to ? t.to : t.from;
- }
-
- string context::
- quote_id_impl (qname const& id) const
- {
- string r;
-
- bool f (true);
- for (qname::iterator i (id.begin ()); i < id.end (); ++i)
- {
- if (i->empty ())
- continue;
-
- if (f)
- f = false;
- else
- r += '.';
-
- r += '"';
- r.append (*i, 0, 30); // Max identifier length is 30.
- r += '"';
- }
-
- return r;
- }
-
- string context::
- database_type_impl (semantics::type& t,
- semantics::names* hint,
- bool id,
- bool* null)
- {
- string r (base_context::database_type_impl (t, hint, id, null));
-
- if (!r.empty ())
- return r;
-
- using semantics::array;
-
- // char[N] mapping.
- //
- if (array* a = dynamic_cast<array*> (&t))
- {
- semantics::type& bt (a->base_type ());
- if (bt.is_a<semantics::fund_char> ())
- {
- unsigned long long n (a->size ());
-
- if (n == 0)
- return r;
- else if (n == 1)
- r = "CHAR";
- else
- {
- r = "VARCHAR2";
- n--;
- }
-
- // Oracle VARCHAR2 limit is 4000 bytes. Since there are no good
- // alternatives (CLOB?), let the user specify the mapping.
- //
- if (n > 4000)
- return "";
-
- // Allow empty VARCHAR2 values.
- //
- if (null != 0 && r == "VARCHAR2")
- *null = true;
-
- ostringstream ostr;
- ostr << n;
- r += '(';
- r += ostr.str ();
- r += ')';
- }
- }
-
- return r;
- }
-
- bool context::
- unsigned_integer (semantics::type& t)
- {
- semantics::type* wt (wrapper (t));
- const string& s ((wt == 0 ? t : utype (*wt)).name ());
-
- return s == "bool" ||
- s == "unsigned char" ||
- s == "short unsigned int" ||
- s == "unsigned int" ||
- s == "long unsigned int" ||
- s == "long long unsigned int";
- }
-
- qname context::
- sequence_name (qname const& table)
- {
- string n;
-
- if (options.sequence_suffix ().count (db) != 0)
- n = table.uname () + options.sequence_suffix ()[db];
- else
- n = compose_name (table.uname (), "seq");
-
- n = transform_name (n, sql_name_sequence);
-
- qname r (table.qualifier ());
- r.append (n);
- return r;
- }
-
- //
- // SQL type parsing.
- //
-
- sql_type const& context::
- parse_sql_type (string const& t, semantics::data_member& m, bool custom)
- {
- // If this proves to be too expensive, we can maintain a cache of
- // parsed types across contexts.
- //
- data::sql_type_cache::iterator i (data_->sql_type_cache_.find (t));
-
- if (i != data_->sql_type_cache_.end ()
- && (custom ? i->second.custom_cached : i->second.straight_cached))
- {
- return (custom ? i->second.custom : i->second.straight);
- }
- else
- {
- try
- {
- sql_type st (
- parse_sql_type (
- t,
- custom ? &unit.get<custom_db_types> ("custom-db-types") : 0));
-
- if (custom)
- return data_->sql_type_cache_[t].cache_custom (st);
- else
- return data_->sql_type_cache_[t].cache_straight (st);
- }
- catch (invalid_sql_type const& e)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: " << e.message () << endl;
-
- throw operation_failed ();
- }
- }
- }
-
- inline sql_type
- error (bool fail, string const& m)
- {
- if (!fail)
- return sql_type ();
- else
- throw context::invalid_sql_type (m);
- }
-
- sql_type context::
- parse_sql_type (string sqlt, custom_db_types const* ct)
- {
- try
- {
- sql_type r;
-
- // First run the type through the custom mapping, if requested.
- //
- if (ct != 0)
- {
- for (custom_db_types::const_iterator i (ct->begin ());
- i != ct->end (); ++i)
- {
- custom_db_type const& t (*i);
-
- if (t.type.match (sqlt))
- {
- r.to = t.type.replace (sqlt, t.to);
- r.from = t.type.replace (sqlt, t.from);
- sqlt = t.type.replace (sqlt, t.as);
- break;
- }
- }
- }
-
- sql_lexer l (sqlt);
-
- // While most type names use single identifier, there are
- // a couple of exceptions to this rule:
- //
- // CHARACTER VARYING (VARCHAR2)
- // CHAR VARYING (VARCHAR2)
- // NATIONAL CHARACTER (NCHAR)
- // NATIONAL CHAR (NCHAR)
- // NCHAR VARYING (NVARCHAR2)
- // NATIONAL CHARACTER VARYING (NVARCHAR2)
- // NATIONAL CHAR VARYING (NVARCHAR2)
- // NCHAR VARYING (NVARCHAR2)
- // DOUBLE PRECISION (FLOAT(126))
- // INTERVAL YEAR TO MONTH
- // INTERVAL DAY TO SECOND
- //
- enum state
- {
- parse_identifier,
- parse_prec,
- parse_done
- };
-
- state s (parse_identifier);
- string prefix;
- sql_token t (l.next ());
-
- while (t.type () != sql_token::t_eos)
- {
- sql_token::token_type tt (t.type ());
-
- switch (s)
- {
- case parse_identifier:
- {
- if (tt == sql_token::t_identifier)
- {
- string const& id (context::upcase (t.identifier ()));
-
- //
- // Numeric types.
- //
- if ((id == "NUMBER") && prefix.empty ())
- {
- // If NUMBER has no precision/scale, then it is a floating-
- // point number. We indicate this by having no precision.
- //
- r.type = sql_type::NUMBER;
- s = parse_prec;
- }
- else if ((id == "DEC" || id == "DECIMAL" || id == "NUMERIC")
- && prefix.empty ())
- {
- // DEC, DECIMAL, and NUMERIC are equivalent to NUMBER in
- // all ways except that they may not represent a floating
- // point number. The scale defaults to zero.
- //
- r.type = sql_type::NUMBER;
- s = parse_prec;
- }
- else if ((id == "INT" || id == "INTEGER" || id == "SMALLINT")
- && prefix.empty ())
- {
- // INT, INTEGER, and SMALLINT map to NUMBER(38). They may not
- // have precision or scale explicitly specified.
- //
- r.type = sql_type::NUMBER;
- r.prec = true;
- r.prec_value = 38;
-
- s = parse_done;
- }
- //
- // Floating point types.
- //
- else if (id == "FLOAT" && prefix.empty ())
- {
- r.type = sql_type::FLOAT;
- r.prec = true;
- r.prec_value = 126;
-
- s = parse_prec;
- }
- else if (id == "DOUBLE" && prefix.empty ())
- {
- prefix = id;
- }
- else if (id == "PRECISION" && prefix == "DOUBLE")
- {
- r.type = sql_type::FLOAT;
- r.prec = true;
- r.prec_value = 126;
-
- s = parse_done;
- }
- else if (id == "REAL" && prefix.empty ())
- {
- r.type = sql_type::FLOAT;
- r.prec = true;
- r.prec_value = 63;
-
- s = parse_done;
- }
- else if (id == "BINARY_FLOAT" && prefix.empty ())
- {
- r.type = sql_type::BINARY_FLOAT;
- s = parse_done;
- }
- else if (id == "BINARY_DOUBLE" && prefix.empty ())
- {
- r.type = sql_type::BINARY_DOUBLE;
- s = parse_done;
- }
- //
- // Date-time types.
- //
- else if (id == "DATE" && prefix.empty ())
- {
- r.type = sql_type::DATE;
- s = parse_done;
- }
- else if (id == "TIMESTAMP" && prefix.empty ())
- {
- prefix = id;
- }
- else if (id == "INTERVAL" && prefix.empty ())
- {
- prefix = id;
- }
- else if (id == "YEAR" && prefix == "INTERVAL")
- {
- prefix += " ";
- prefix += id;
-
- r.prec = true;
- r.prec_value = 2;
- s = parse_prec;
- }
- else if (id == "DAY" && prefix == "INTERVAL")
- {
- prefix += " ";
- prefix += id;
-
- r.prec = true;
- r.prec_value = 2;
- s = parse_prec;
- }
- else if (id == "TO" &&
- (prefix == "INTERVAL YEAR" ||
- prefix == "INTERVAL DAY"))
- {
- prefix += " ";
- prefix += id;
- }
- else if (id == "MONTH" && prefix == "INTERVAL YEAR TO")
- {
- r.type = sql_type::INTERVAL_YM;
- s = parse_done;
- }
- else if (id == "SECOND" && prefix == "INTERVAL DAY TO")
- {
- r.type = sql_type::INTERVAL_DS;
-
- // Store seconds precision in scale since prec holds
- // the days precision.
- //
- r.scale = true;
- r.scale_value = 6;
- s = parse_prec;
- }
- //
- // Timestamp with time zone (not supported).
- //
- else if (id == "WITH" && prefix == "TIMESTAMP")
- {
- prefix += " ";
- prefix += id;
- }
- else if (id == "TIME" &&
- (prefix == "TIMESTAMP WITH" ||
- prefix == "TIMESTAMP WITH LOCAL"))
- {
- prefix += " ";
- prefix += id;
- }
- else if (id == "LOCAL" && prefix == "TIMESTAMP WITH")
- {
- prefix += " ";
- prefix += id;
- }
- else if (id == "ZONE" &&
- (prefix == "TIMESTAMP WITH LOCAL TIME" ||
- prefix == "TIMESTAMP WITH TIME"))
- {
- return error (ct, "Oracle timestamps with time zones are "
- "not currently supported");
- }
- //
- // String and binary types.
- //
- else if (id == "CHAR")
- {
- prefix += prefix.empty () ? "" : " ";
- prefix += id;
- }
- else if (id == "CHARACTER")
- {
- prefix += prefix.empty () ? "" : " ";
- prefix += id;
- }
- else if (id == "NCHAR")
- {
- prefix += prefix.empty () ? "" : " ";
- prefix += id;
- }
- else if (id == "VARCHAR" || id == "VARCHAR2")
- {
- // VARCHAR is currently mapped to VARCHAR2 in Oracle server.
- // However, this may change in future versions.
- //
- r.type = sql_type::VARCHAR2;
- r.byte_semantics = true;
- s = parse_prec;
- }
- else if (id == "NVARCHAR2")
- {
- r.type = sql_type::NVARCHAR2;
- r.byte_semantics = false;
- s = parse_prec;
- }
- else if (id == "VARYING")
- {
- // VARYING always appears at the end of an identifier.
- //
- if (prefix == "CHAR" || prefix == "CHARACTER")
- {
- r.type = sql_type::VARCHAR2;
- r.byte_semantics = true;
- }
- else if (prefix == "NCHAR" ||
- prefix == "NATIONAL CHAR" ||
- prefix == "NATIONAL CHARACTER")
- {
- r.type = sql_type::NVARCHAR2;
- r.byte_semantics = false;
- }
-
- s = parse_prec;
- }
- else if (id == "NATIONAL" && prefix.empty ())
- {
- prefix = id;
- }
- else if (id == "RAW" && prefix.empty ())
- {
- r.type = sql_type::RAW;
- s = parse_prec;
- }
- //
- // LOB types.
- //
- else if (id == "BLOB" && prefix.empty ())
- {
- r.type = sql_type::BLOB;
- s = parse_done;
- }
- else if (id == "CLOB" && prefix.empty ())
- {
- r.type = sql_type::CLOB;
- s = parse_done;
- }
- else if (id == "NCLOB" && prefix.empty ())
- {
- r.type = sql_type::NCLOB;
- s = parse_done;
- }
- //
- // LONG types.
- //
- else if (id == "LONG")
- return error (ct, "Oracle LONG types are not supported");
- else
- return error (ct, "unknown Oracle type '" +
- t.identifier () + "'");
-
- t = l.next ();
- continue;
- }
- else if (!prefix.empty ())
- {
- // Some prefixes can also be type names if not followed
- // by the actual type name.
- //
-
- if (prefix == "CHAR" || prefix == "CHARACTER")
- {
- r.type = sql_type::CHAR;
- r.byte_semantics = true;
- r.prec = true;
- r.prec_value = 1;
- }
- else if (prefix == "NCHAR" ||
- prefix == "NATIONAL CHAR" ||
- prefix == "NATIONAL CHARACTER")
- {
- r.type = sql_type::NCHAR;
- r.byte_semantics = false;
- r.prec = true;
- r.prec_value = 1;
- }
- else if (prefix == "TIMESTAMP")
- {
- r.type = sql_type::TIMESTAMP;
- r.prec = true;
- r.prec_value = 6;
- }
- else
- return error (ct, "incomplete Oracle type declaration: '" +
- prefix + "'");
-
- // All of the possible types handled in this block can take
- // an optional precision specifier. Set the state and fall
- // through to the parse_prec handler.
- //
- s = parse_prec;
- }
- else
- {
- assert (r.type == sql_type::invalid);
- return error (ct, "unexepected '" + t.literal () +
- "' in Oracle type declaration");
- }
- }
- // Fall through.
- case parse_prec:
- {
- if (t.punctuation () == sql_token::p_lparen)
- {
- t = l.next ();
-
- if (t.type () != sql_token::t_int_lit)
- {
- return error (ct, "integer size/precision expected in "
- "Oracle type declaration");
- }
-
- // Parse the precision.
- //
- {
- unsigned short v;
- istringstream is (t.literal ());
-
- if (!(is >> v && is.eof ()))
- {
- return error (ct, "invalid prec value '" + t.literal () +
- "' in Oracle type declaration");
- }
-
- // Store seconds precision in scale since prec holds
- // the days precision for INTERVAL DAY TO SECOND.
- //
- if (r.type == sql_type::INTERVAL_DS)
- {
- r.scale = true;
- r.scale_value = static_cast<short> (v);
- }
- else
- {
- r.prec = true;
- r.prec_value = v;
- }
-
- t = l.next ();
- }
-
- // Parse the scale if present.
- //
- if (t.punctuation () == sql_token::p_comma)
- {
- // Scale can only be specified for NUMBER.
- //
- if (r.type != sql_type::NUMBER)
- {
- return error (ct, "invalid scale in Oracle type "
- "declaration");
- }
-
- t = l.next ();
-
- if (t.type () != sql_token::t_int_lit)
- {
- return error (ct, "integer scale expected in Oracle type "
- "declaration");
- }
-
- short v;
- istringstream is (t.literal ());
-
- if (!(is >> v && is.eof ()))
- {
- return error (ct, "invalid scale value '" + t.literal () +
- "' in Oracle type declaration");
- }
-
- r.scale = true;
- r.scale_value = v;
-
- t = l.next ();
- }
- else if (t.type () == sql_token::t_identifier)
- {
- const string& id (context::upcase (t.identifier ()));
-
- if (id == "CHAR")
- r.byte_semantics = false;
- else if (id != "BYTE")
- {
- return error (ct, "invalid keyword '" + t.literal () +
- "' in Oracle type declaration");
- }
-
- t = l.next ();
- }
-
- if (t.punctuation () != sql_token::p_rparen)
- {
- return error (ct, "expected ')' in Oracle type declaration");
- }
- else
- t = l.next ();
- }
-
- s = r.type == sql_type::invalid ? parse_identifier : parse_done;
- continue;
- }
- case parse_done:
- {
- return error (ct, "unexepected '" + t.literal () + "' in Oracle "
- "type declaration");
- break;
- }
- }
- }
-
- // Some prefixes can also be type names if not followed by the actual
- // type name.
- //
- if (r.type == sql_type::invalid)
- {
- if (!prefix.empty ())
- {
- if (prefix == "CHAR" || prefix == "CHARACTER")
- {
- r.type = sql_type::CHAR;
- r.byte_semantics = true;
- r.prec = true;
- r.prec_value = 1;
- }
- else if (prefix == "NCHAR" ||
- prefix == "NATIONAL CHAR" ||
- prefix == "NATIONAL CHARACTER")
- {
- r.type = sql_type::NCHAR;
- r.byte_semantics = false;
- r.prec = true;
- r.prec_value = 1;
- }
- else if (prefix == "TIMESTAMP")
- {
- r.type = sql_type::TIMESTAMP;
- r.prec = true;
- r.prec_value = 6;
- }
- else
- return error (ct, "incomplete Oracle type declaration: '" +
- prefix + "'");
- }
- else
- return error (ct, "invalid Oracle type declaration");
- }
-
- return r;
- }
- catch (sql_lexer::invalid_input const& e)
- {
- return error (ct, "invalid Oracle type declaration: " + e.message);
- }
- }
- }
-}
diff --git a/odb/relational/oracle/context.hxx b/odb/relational/oracle/context.hxx
deleted file mode 100644
index 6c55853..0000000
--- a/odb/relational/oracle/context.hxx
+++ /dev/null
@@ -1,188 +0,0 @@
-// file : odb/relational/oracle/context.hxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#ifndef ODB_RELATIONAL_ORACLE_CONTEXT_HXX
-#define ODB_RELATIONAL_ORACLE_CONTEXT_HXX
-
-#include <map>
-
-#include <odb/relational/context.hxx>
-
-namespace relational
-{
- namespace oracle
- {
- struct sql_type
- {
- // Keep the order in each block of types.
- //
- enum core_type
- {
- // Numeric types.
- //
- NUMBER,
- FLOAT,
-
- // Floating point types.
- //
- BINARY_FLOAT,
- BINARY_DOUBLE,
-
- // Date-time types.
- //
- DATE,
- TIMESTAMP,
- INTERVAL_YM,
- INTERVAL_DS,
-
- // String and binary types.
- //
- CHAR,
- NCHAR,
- VARCHAR2,
- NVARCHAR2,
- RAW,
-
- // LOB types.
- //
- BLOB,
- CLOB,
- NCLOB,
-
- // Invalid type.
- //
- invalid
- };
-
- sql_type () :
- type (invalid), prec (false), scale (false), byte_semantics (true)
- {
- }
-
- core_type type;
-
- bool prec;
- unsigned short prec_value; // Oracle max value is 4000.
-
- bool scale;
- short scale_value; // Oracle min value is -84. Max value is 127.
-
- bool byte_semantics;
-
- // Conversion expressions for custom database types.
- //
- std::string to;
- std::string from;
- };
-
- class context: public virtual relational::context
- {
- public:
- sql_type const&
- parse_sql_type (string const&,
- semantics::data_member&,
- bool custom = true);
- public:
- struct invalid_sql_type
- {
- invalid_sql_type (string const& message): message_ (message) {}
-
- string const&
- message () const {return message_;}
-
- private:
- string message_;
- };
-
- // If custom_db_types is NULL, then this function returns
- // invalid type instead of throwing in case an unknown type
- // is encountered.
- //
- static sql_type
- parse_sql_type (string, custom_db_types const* = 0);
-
- public:
- // If necessary, unwraps.
- //
- static bool
- unsigned_integer (semantics::type&);
-
- public:
- // Construct sequence name from a given table name.
- //
- qname
- sequence_name (qname const& table);
-
- protected:
- virtual string const&
- convert_expr (string const&, semantics::data_member&, bool);
-
- virtual string
- quote_id_impl (qname const&) const;
-
- protected:
- virtual string
- database_type_impl (semantics::type&, semantics::names*, bool, bool*);
-
- public:
- virtual
- ~context ();
-
- context ();
- context (std::ostream&,
- semantics::unit&,
- options_type const&,
- features_type&,
- sema_rel::model*);
-
- static context&
- current ()
- {
- return *current_;
- }
-
- private:
- static context* current_;
-
- private:
- struct data: base_context::data
- {
- data (std::ostream& os): base_context::data (os) {}
-
- struct sql_type_cache_entry
- {
- sql_type_cache_entry ()
- : custom_cached (false), straight_cached (false) {}
-
- sql_type const&
- cache_custom (sql_type const& t)
- {
- custom = t;
- custom_cached = true;
- return custom;
- }
-
- sql_type const&
- cache_straight (sql_type const& t)
- {
- straight = t;
- straight_cached = true;
- return straight;
- }
-
- sql_type custom; // With custom mapping.
- sql_type straight; // Without custom mapping.
-
- bool custom_cached;
- bool straight_cached;
- };
-
- typedef std::map<string, sql_type_cache_entry> sql_type_cache;
- sql_type_cache sql_type_cache_;
- };
- data* data_;
- };
- }
-}
-
-#endif // ODB_RELATIONAL_ORACLE_CONTEXT_HXX
diff --git a/odb/relational/oracle/header.cxx b/odb/relational/oracle/header.cxx
deleted file mode 100644
index bf50bb2..0000000
--- a/odb/relational/oracle/header.cxx
+++ /dev/null
@@ -1,230 +0,0 @@
-// file : odb/relational/oracle/header.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/header.hxx>
-
-#include <odb/relational/oracle/common.hxx>
-#include <odb/relational/oracle/context.hxx>
-
-namespace relational
-{
- namespace oracle
- {
- namespace header
- {
- namespace relational = relational::header;
-
- struct image_type: relational::image_type, context
- {
- image_type (base const& x): base (x) {};
-
- virtual void
- image_extra (type& c)
- {
- if (!(composite (c) || (abstract (c) && !polymorphic (c))))
- {
- type* poly_root (polymorphic (c));
-
- // If this is a polymorphic type, only add callback to the root.
- //
- if (poly_root == 0 || poly_root == &c)
- {
- bool gc (options.generate_query ());
-
- if (gc)
- os << "oracle::change_callback change_callback_;"
- << endl;
-
- os << "oracle::change_callback*" << endl
- << "change_callback ()"
- << "{";
-
- if (gc)
- os << "return &change_callback_;";
- else
- os << "return 0;";
-
- os << "}";
- }
- }
- }
- };
- entry<image_type> image_type_;
-
- struct image_member: relational::image_member_impl<sql_type>,
- member_base
- {
- image_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x) {}
-
- virtual void
- traverse_int32 (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_int64 (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_big_int (member_info& mi)
- {
- // Each significant base-100 digit requires a byte of storage
- // in the manitissa. The default precision is 38 decimal digits,
- // which is equivalent to 19 base-100 digits.
- //
- size_t n (19);
-
- if (mi.st->prec)
- n = mi.st->prec_value / 2 + mi.st->prec_value % 2;
-
- // We require an additional byte for each of the exponent and
- // negative value terminator values.
- //
- n += 2;
-
- os << "char " << mi.var << "value[" << n << "];"
- << "ub2 " << mi.var << "size;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_double (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_big_float (member_info& mi)
- {
- // big_float is mapped to the OCI type SQLT_NUM, which requires 21
- // bytes of storage.
- //
- os << "char " << mi.var << "value[21];"
- << "ub2 " << mi.var << "size;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << "char " << mi.var << "value[7];"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_timestamp (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_interval_ym (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_interval_ds (member_info& mi)
- {
- os << image_type << " " << mi.var << "value;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- size_t n (mi.st->prec ? mi.st->prec_value : 1);
-
- // National characters can be either UTF-8 or UTF-16 encoded,
- // both of which have a maximum character encoding size of 4
- // bytes. Database character set can also be UTF-8 so if the
- // size is specified in characters, then conservatively assume
- // each character can take up to 4 bytes.
- //
- if (!mi.st->byte_semantics) // N*CHAR always has CHAR semantics.
- n *= 4;
-
- if (mi.st->type == sql_type::VARCHAR2 ||
- mi.st->type == sql_type::NVARCHAR2)
- n = n > 4000 ? 4000 : n;
- else
- n = n > 2000 ? 2000 : n;
-
- os << "char " << mi.var << "value[" << n << "];"
- << "ub2 " << mi.var << "size;"
- << "sb2 " << mi.var << "indicator;"
- << endl;
- }
-
- virtual void
- traverse_lob (member_info& mi)
- {
- os << "mutable " << image_type << " " << mi.var << "callback;"
- << "sb2 " << mi.var << "indicator;"
- << "oracle::lob " << mi.var << "lob;"
- << endl;
- }
- };
- entry<image_member> image_member_;
-
- struct class1: relational::class1
- {
- class1 (base const& x): base (x) {}
-
- virtual void
- object_public_extra_pre (type& c)
- {
- bool abst (abstract (c));
-
- type* poly_root (polymorphic (c));
- bool poly (poly_root != 0);
- bool poly_derived (poly && poly_root != &c);
-
- if (poly_derived || (abst && !poly))
- return;
-
- // Bulk operations batch size.
- //
- {
- unsigned long long b (c.count ("bulk")
- ? c.get<unsigned long long> ("bulk")
- : 1);
-
- os << "static const std::size_t batch = " << b << "UL;"
- << endl;
- }
- }
- };
- entry<class1> class1_entry_;
- }
- }
-}
diff --git a/odb/relational/oracle/inline.cxx b/odb/relational/oracle/inline.cxx
deleted file mode 100644
index 1b6d606..0000000
--- a/odb/relational/oracle/inline.cxx
+++ /dev/null
@@ -1,42 +0,0 @@
-// file : odb/relational/oracle/inline.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/inline.hxx>
-
-#include <odb/relational/oracle/common.hxx>
-#include <odb/relational/oracle/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace oracle
- {
- namespace inline_
- {
- namespace relational = relational::inline_;
-
- struct null_member: relational::null_member_impl<sql_type>,
- member_base
- {
- null_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- traverse_simple (member_info& mi)
- {
- if (get_)
- os << "r = r && i." << mi.var << "indicator == -1;";
- else
- os << "i." << mi.var << "indicator = -1;";
- }
- };
- entry<null_member> null_member_;
- }
- }
-}
diff --git a/odb/relational/oracle/model.cxx b/odb/relational/oracle/model.cxx
deleted file mode 100644
index b65e201..0000000
--- a/odb/relational/oracle/model.cxx
+++ /dev/null
@@ -1,64 +0,0 @@
-// file : odb/relational/oracle/model.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <sstream>
-
-#include <odb/relational/model.hxx>
-
-#include <odb/relational/oracle/common.hxx>
-#include <odb/relational/oracle/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace oracle
- {
- namespace model
- {
- namespace relational = relational::model;
-
- struct object_columns: relational::object_columns, context
- {
- object_columns (base const& x): base (x) {}
-
- virtual string
- default_enum (semantics::data_member& m, tree en, string const&)
- {
- // Make sure the column is mapped to Oracle NUMBER.
- //
- sql_type const& t (parse_sql_type (column_type (), m, false));
- if (t.type != sql_type::NUMBER)
- {
- cerr << m.file () << ":" << m.line () << ":" << m.column ()
- << ": error: column with default value specified as C++ "
- << "enumerator must map to Oracle NUMBER" << endl;
-
- throw operation_failed ();
- }
-
- using semantics::enumerator;
-
- enumerator& e (dynamic_cast<enumerator&> (*unit.find (en)));
-
- ostringstream ostr;
-
- if (e.enum_ ().unsigned_ ())
- ostr << e.value ();
- else
- ostr << static_cast<long long> (e.value ());
-
- return ostr.str ();
- }
-
- virtual void
- primary_key (sema_rel::primary_key& pk)
- {
- if (pk.auto_ ())
- pk.extra ()["sequence"] = sequence_name (table_.name ()).string ();
- }
- };
- entry<object_columns> object_columns_;
- }
- }
-}
diff --git a/odb/relational/oracle/schema.cxx b/odb/relational/oracle/schema.cxx
deleted file mode 100644
index 75100b1..0000000
--- a/odb/relational/oracle/schema.cxx
+++ /dev/null
@@ -1,696 +0,0 @@
-// file : odb/relational/oracle/schema.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <map>
-#include <utility> // pair
-
-#include <odb/diagnostics.hxx>
-
-#include <odb/relational/schema.hxx>
-
-#include <odb/relational/oracle/common.hxx>
-#include <odb/relational/oracle/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace oracle
- {
- namespace schema
- {
- namespace relational = relational::schema;
- using relational::table_set;
-
- struct sql_emitter: relational::sql_emitter
- {
- sql_emitter (const base& x): base (x) {}
-
- virtual void
- line (const std::string& l)
- {
- // SQLPlus doesn't like empty line in the middle of a statement.
- //
- if (!l.empty ())
- {
- base::line (l);
- last_ = l;
- }
- }
-
- virtual void
- post ()
- {
- if (!first_) // Ignore empty statements.
- {
- if (last_ == "END;")
- os << endl
- << '/' << endl
- << endl;
-
- else
- os << ';' << endl
- << endl;
- }
- }
-
- private:
- string last_;
- };
- entry<sql_emitter> sql_emitter_;
-
- //
- // File.
- //
-
- struct sql_file: relational::sql_file, context
- {
- sql_file (const base& x): base (x) {}
-
- virtual void
- prologue ()
- {
- // Quiet down SQLPlus and make sure it exits with an error
- // code if there is an error.
- //
- os << "SET FEEDBACK OFF;" << endl
- << "WHENEVER SQLERROR EXIT FAILURE;" << endl
- << "WHENEVER OSERROR EXIT FAILURE;" << endl
- << endl;
- }
-
- virtual void
- epilogue ()
- {
- os << "EXIT;" << endl;
- }
- };
- entry<sql_file> sql_file_;
-
- //
- // Drop.
- //
-
- struct drop_column: relational::drop_column, context
- {
- drop_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::drop_column& dc)
- {
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- os << quote_id (dc.name ());
- }
- };
- entry<drop_column> drop_column_;
-
- struct drop_foreign_key: relational::drop_foreign_key, context
- {
- drop_foreign_key (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::drop_foreign_key& dfk)
- {
- os << endl;
- drop (dfk);
- }
- };
- entry<drop_foreign_key> drop_foreign_key_;
-
- struct drop_index: relational::drop_index, context
- {
- drop_index (base const& x): base (x) {}
-
- virtual string
- name (sema_rel::index& in)
- {
- // In Oracle, index names can be qualified with the schema.
- //
- sema_rel::table& t (static_cast<sema_rel::table&> (in.scope ()));
- sema_rel::qname n (t.name ().qualifier ());
- n.append (in.name ());
- return quote_id (n);
- }
- };
- entry<drop_index> drop_index_;
-
- struct drop_table: relational::drop_table, context
- {
- drop_table (base const& x): base (x) {}
-
- virtual void
- drop (sema_rel::table& t, bool migration)
- {
- using sema_rel::primary_key;
-
- sema_rel::table::names_iterator i (t.find ("")); // Special name.
- primary_key* pk (i != t.names_end ()
- ? &dynamic_cast<primary_key&> (i->nameable ())
- : 0);
-
- string qt (quote_id (t.name ()));
- string qs (pk != 0 && pk->auto_ ()
- ? quote_id (qname::from_string (pk->extra ()["sequence"]))
- : "");
-
- if (migration)
- {
- pre_statement ();
- os << "DROP TABLE " << qt << endl;
- post_statement ();
-
- // Drop the sequence if we have auto primary key.
- //
- if (!qs.empty ())
- {
- pre_statement ();
- os << "DROP SEQUENCE " << qs << endl;
- post_statement ();
- }
- }
- else
- {
- // Oracle has no IF EXISTS conditional for dropping objects. The
- // PL/SQL approach below seems to be the least error-prone and the
- // most widely used of the alternatives.
- //
- pre_statement ();
- os << "BEGIN" << endl
- << " BEGIN" << endl
- << " EXECUTE IMMEDIATE 'DROP TABLE " << qt << " CASCADE " <<
- "CONSTRAINTS';" << endl
- << " EXCEPTION" << endl
- << " WHEN OTHERS THEN" << endl
- << " IF SQLCODE != -942 THEN RAISE; END IF;" << endl
- << " END;" << endl;
-
- // Drop the sequence if we have auto primary key.
- //
- if (!qs.empty ())
- {
- os << " BEGIN" << endl
- << " EXECUTE IMMEDIATE 'DROP SEQUENCE " << qs <<
- "';" << endl
- << " EXCEPTION" << endl
- << " WHEN OTHERS THEN" << endl
- << " IF SQLCODE != -2289 THEN RAISE; END IF;" << endl
- << " END;" << endl;
- }
-
- os << "END;" << endl;
- post_statement ();
- }
- }
-
- virtual void
- traverse (sema_rel::table& t, bool migration)
- {
- // For migration drop foreign keys explicitly in pre-migration.
- //
- if (migration)
- {
- base::traverse (t, migration);
- return;
- }
-
- // For schema creation we use the CASCADE clause to drop foreign
- // keys.
- //
- if (pass_ != 2)
- return;
-
- drop (t, migration);
- }
- };
- entry<drop_table> drop_table_;
-
- //
- // Create.
- //
- static sema_rel::uname
- truncate (location const& l, const char* kind, sema_rel::uname n, bool w)
- {
- if (n.size () > 30)
- {
- if (w)
- warn (l) << kind << " name '" << n << "' is longer than 30 "
- << "characters and will be truncated" << endl;
-
- n.resize (30);
- }
-
- return n;
- }
-
- static sema_rel::qname
- truncate (location const& l,
- const char* kind,
- sema_rel::qname const& n,
- bool w)
- {
- // Don't bother verifying the schema name since that is
- // specified explicitly and in a single place.
- //
- qname r (n.qualifier ());
- r.append (truncate (l, kind, n.uname (), w));
- return r;
- }
-
- template <typename N>
- struct scope
- {
- typedef std::map<N, pair<N, location> > map;
-
- scope (const char* k, const char* p, bool w)
- : kind_ (k), prag_ (p), warn_ (w) {}
-
- void
- check (location const& l, N const& n)
- {
- N tn (truncate (l, kind_, n, warn_));
-
- pair<typename map::iterator, bool> r (
- map_.insert (make_pair (tn, make_pair (n, l))));
-
- if (r.second)
- return;
-
- error (l) << kind_ << " name '" << tn << "' conflicts with an "
- << "already defined " << kind_ << " name" << endl;
-
- if (tn != n)
- info (l) << kind_ << " name '" << tn << "' is truncated '"
- << n << "'" << endl;
-
- N const& n1 (r.first->second.first);
- location const& l1 (r.first->second.second);
-
- info (l1) << "conflicting " << kind_ << " is defined here" << endl;
-
- if (tn != n)
- info (l1) << "conflicting " << kind_ << " name '" << tn
- << "' is truncated '" << n1 << "'" << endl;
-
- info (l) << "use #pragma db " << prag_ << " to change one of "
- << "the names" << endl;
-
- throw operation_failed ();
- }
-
- void
- clear () {map_.clear ();}
-
- const char* kind_;
- const char* prag_;
- bool warn_;
- map map_;
- };
-
- struct scopes
- {
- scopes (bool warn)
- : tables ("table", "table", warn),
- fkeys ("foreign key", "column", warn), // Change column name.
- indexes ("index", "index", warn),
- sequences ("sequence", "table", warn), // Change table name.
- columns ("column", "column", warn) {}
-
- // In Oracle, all these entities are in their own name spaces,
- // as in an index and a foreign key with the same name do not
- // conflict.
- //
- scope<sema_rel::qname> tables;
- scope<sema_rel::uname> fkeys; // Global but can't have schema.
- scope<sema_rel::qname> indexes;
- scope<sema_rel::qname> sequences;
- scope<sema_rel::uname> columns;
- };
-
- struct create_column: relational::create_column, context
- {
- create_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::column& c)
- {
- // Check name trunction and conflicts.
- //
- if (scopes* s = static_cast<scopes*> (context::extra))
- s->columns.check (c.get<location> ("cxx-location"), c.name ());
-
- base::traverse (c);
- }
-
- virtual void
- traverse (sema_rel::add_column& ac)
- {
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- create (ac);
- }
-
- virtual void
- constraints (sema_rel::column& c, sema_rel::primary_key* pk)
- {
- // Oracle wants DEFAULT before NULL even though we can end
- // up with mouthfulls like DEFAULT NULL NULL.
- //
- if (!c.default_ ().empty ())
- os << " DEFAULT " << c.default_ ();
-
- null (c);
-
- // If this is a single-column primary key, generate it inline.
- //
- if (pk != 0 && pk->contains_size () == 1)
- primary_key ();
-
- if (pk != 0 && pk->auto_ ())
- auto_ (*pk);
- }
- };
- entry<create_column> create_column_;
-
- struct create_foreign_key: relational::create_foreign_key, context
- {
- create_foreign_key (base const& x): base (x) {}
-
- virtual void
- traverse_create (sema_rel::foreign_key& fk)
- {
- // Check name trunction and conflicts.
- //
- if (scopes* s = static_cast<scopes*> (context::extra))
- s->fkeys.check (fk.get<location> ("cxx-location"), fk.name ());
-
- base::traverse_create (fk);
- }
-
- virtual void
- traverse_add (sema_rel::foreign_key& fk)
- {
- // Check name trunction and conflicts.
- //
- if (scopes* s = static_cast<scopes*> (context::extra))
- s->fkeys.check (fk.get<location> ("cxx-location"), fk.name ());
-
- os << endl
- << " ADD CONSTRAINT ";
- create (fk);
- }
- };
- entry<create_foreign_key> create_foreign_key_;
-
- struct create_index: relational::create_index, context
- {
- create_index (base const& x): base (x) {}
-
- virtual string
- name (sema_rel::index& in)
- {
- // In Oracle, index names can be qualified with the schema.
- //
- sema_rel::table& t (static_cast<sema_rel::table&> (in.scope ()));
- sema_rel::qname n (t.name ().qualifier ());
- n.append (in.name ());
-
- // Check name trunction and conflicts.
- //
- if (scopes* s = static_cast<scopes*> (context::extra))
- s->indexes.check (in.get<location> ("cxx-location"), n);
-
- return quote_id (n);
- }
- };
- entry<create_index> create_index_;
-
- struct create_table: relational::create_table, context
- {
- create_table (base const& x): base (x) {}
-
- void
- traverse (sema_rel::table& t)
- {
- // Check name trunction and conflicts.
- //
- if (scopes* s = static_cast<scopes*> (context::extra))
- {
- if (pass_ == 1)
- {
- s->tables.check (t.get<location> ("cxx-location"), t.name ());
- s->columns.clear ();
- }
- }
-
- base::traverse (t);
-
- if (pass_ == 1)
- {
- // Create the sequence if we have auto primary key.
- //
- using sema_rel::primary_key;
-
- sema_rel::table::names_iterator i (t.find ("")); // Special name.
- primary_key* pk (i != t.names_end ()
- ? &dynamic_cast<primary_key&> (i->nameable ())
- : 0);
-
- if (pk != 0 && pk->auto_ ())
- {
- // Already qualified with the table's schema, if any.
- //
- sema_rel::qname n (
- qname::from_string (pk->extra ()["sequence"]));
-
- if (scopes* s = static_cast<scopes*> (context::extra))
- s->sequences.check (pk->get<location> ("cxx-location"), n);
-
- pre_statement ();
- os_ << "CREATE SEQUENCE " << quote_id (n) << endl
- << " START WITH 1 INCREMENT BY 1" << endl;
- post_statement ();
- }
- }
- }
- };
- entry<create_table> create_table_;
-
- struct create_model: relational::create_model, context
- {
- create_model (base const& x): base (x) {}
-
- void
- traverse (sema_rel::model& m)
- {
- scopes s (options.oracle_warn_truncation ());
- context::extra = &s;
- base::traverse (m);
- context::extra = 0;
- }
- };
- entry<create_model> create_model_;
-
- //
- // Alter.
- //
-
- struct alter_column: relational::alter_column, context
- {
- alter_column (base const& x): base (x) {}
-
- virtual void
- traverse (sema_rel::column& c)
- {
- // Relax (NULL) in pre and tighten (NOT NULL) in post.
- //
- if (pre_ != c.null ())
- return;
-
- if (first_)
- first_ = false;
- else
- os << "," << endl
- << " ";
-
- os << quote_id (c.name ()) << (c.null () ? " NULL" : " NOT NULL");
- }
- };
- entry<alter_column> alter_column_;
-
- struct alter_table_pre: relational::alter_table_pre, context
- {
- alter_table_pre (base const& x): base (x) {}
-
- virtual void
- alter (sema_rel::alter_table& at)
- {
- // Oracle can only alter certain kinds of things together but
- // grouped one at a time.
- //
- if (check<sema_rel::drop_foreign_key> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ());
-
- instance<drop_foreign_key> dfc (*this);
- trav_rel::unames n (*dfc);
- names (at, n);
- os << endl;
-
- post_statement ();
- }
-
- if (check<sema_rel::add_column> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " ADD (";
-
- instance<create_column> cc (*this);
- trav_rel::unames n (*cc);
- names (at, n);
- os << ")" << endl;
-
- post_statement ();
- }
-
- if (check_alter_column_null (at, true))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " MODIFY (";
-
- bool tl (true); // (Im)perfect forwarding.
- instance<alter_column> ac (*this, tl);
- trav_rel::unames n (*ac);
- names (at, n);
- os << ")" << endl;
-
- post_statement ();
- }
- }
- };
- entry<alter_table_pre> alter_table_pre_;
-
- struct alter_table_post: relational::alter_table_post, context
- {
- alter_table_post (base const& x): base (x) {}
-
- virtual void
- alter (sema_rel::alter_table& at)
- {
- // Oracle can only alter certain kinds of things together but
- // grouped one at a time.
- //
- if (check<sema_rel::drop_column> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " DROP (";
-
- instance<drop_column> dc (*this);
- trav_rel::unames n (*dc);
- names (at, n);
- os << ")" << endl;
-
- post_statement ();
- }
-
- if (check_alter_column_null (at, false))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ()) << endl
- << " MODIFY (";
-
- bool fl (false); // (Im)perfect forwarding.
- instance<alter_column> ac (*this, fl);
- trav_rel::unames n (*ac);
- names (at, n);
- os << ")" << endl;
-
- post_statement ();
- }
-
- if (check<sema_rel::add_foreign_key> (at))
- {
- pre_statement ();
-
- os << "ALTER TABLE " << quote_id (at.name ());
-
- instance<create_foreign_key> cfc (*this);
- trav_rel::unames n (*cfc);
- names (at, n);
- os << endl;
-
- post_statement ();
- }
- }
- };
- entry<alter_table_post> alter_table_post_;
-
- //
- // Schema version table.
- //
-
- struct version_table: relational::version_table, context
- {
- version_table (base const& x)
- : base (x)
- {
- // If the schema name is empty, replace it with a single space
- // to workaround the VARCHAR2 empty/NULL issue.
- //
- if (qs_ == "''")
- qs_ = "' '";
- }
-
- virtual void
- create_table ()
- {
- pre_statement ();
-
- os << "BEGIN" << endl
- << " EXECUTE IMMEDIATE 'CREATE TABLE " << qt_ << " (" << endl
- << " " << qn_ << " VARCHAR2(512) NOT NULL PRIMARY KEY," << endl
- << " " << qv_ << " NUMBER(20) NOT NULL," << endl
- << " " << qm_ << " NUMBER(1) NOT NULL)';" << endl
- << "EXCEPTION" << endl
- << " WHEN OTHERS THEN" << endl
- << " IF SQLCODE != -955 THEN RAISE; END IF;" << endl
- << "END;" << endl;
-
- post_statement ();
- }
-
- virtual void
- create (sema_rel::version v)
- {
- pre_statement ();
-
- os << "MERGE INTO " << qt_ << " USING DUAL ON (" << qn_ << " = " <<
- qs_ << ")" << endl
- << " WHEN NOT MATCHED THEN INSERT (" << endl
- << " " << qn_ << ", " << qv_ << ", " << qm_ << ")" << endl
- << " VALUES (" << qs_ << ", " << v << ", 0)" << endl;
-
- post_statement ();
- }
- };
- entry<version_table> version_table_;
- }
- }
-}
diff --git a/odb/relational/oracle/source.cxx b/odb/relational/oracle/source.cxx
deleted file mode 100644
index adf9864..0000000
--- a/odb/relational/oracle/source.cxx
+++ /dev/null
@@ -1,646 +0,0 @@
-// file : odb/relational/oracle/source.cxx
-// license : GNU GPL v3; see accompanying LICENSE file
-
-#include <odb/relational/source.hxx>
-
-#include <odb/relational/oracle/common.hxx>
-#include <odb/relational/oracle/context.hxx>
-
-using namespace std;
-
-namespace relational
-{
- namespace oracle
- {
- namespace source
- {
- namespace relational = relational::source;
-
- struct query_parameters: relational::query_parameters, context
- {
- query_parameters (base const& x): base (x), i_ (0) {}
-
- virtual string
- next (semantics::data_member&, const string&, const string&)
- {
- ostringstream ss;
- ss << ":" << ++i_;
-
- return ss.str ();
- }
-
- virtual string
- auto_id (semantics::data_member&, const string&, const string&)
- {
- return quote_id (sequence_name (table_)) + ".nextval";
- }
-
- private:
- size_t i_;
- };
- entry<query_parameters> query_parameters_;
-
- namespace
- {
- const char* string_buffer_types[] =
- {
- "oracle::bind::string", // CHAR
- "oracle::bind::nstring", // NCHAR
- "oracle::bind::string", // VARCHAR2
- "oracle::bind::nstring", // NVARCHAR2
- "oracle::bind::raw" // RAW
- };
-
- const char* lob_buffer_types[] =
- {
- "oracle::bind::blob",
- "oracle::bind::clob",
- "oracle::bind::nclob"
- };
- }
-
- //
- // bind
- //
-
- struct bind_member: relational::bind_member_impl<sql_type>,
- member_base
- {
- bind_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- traverse_int32 (member_info& mi)
- {
- os << b << ".type = oracle::bind::" <<
- (unsigned_integer (mi.t) ? "uinteger" : "integer") << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".capacity = 4;"
- << b << ".size = 0;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_int64 (member_info& mi)
- {
- os << b << ".type = oracle::bind::" <<
- (unsigned_integer (mi.t) ? "uinteger" : "integer") << ";"
- << b << ".buffer= &" << arg << "." << mi.var << "value;"
- << b << ".capacity = 8;"
- << b << ".size = 0;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_big_int (member_info& mi)
- {
- os << b << ".type = oracle::bind::number;"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".capacity = static_cast<ub4> (sizeof (" << arg <<
- "." << mi.var << "value));"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << b << ".type = oracle::bind::binary_float;"
- << b << ".buffer= &" << arg << "." << mi.var << "value;"
- << b << ".capacity = 4;"
- << b << ".size = 0;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_double (member_info& mi)
- {
- os << b << ".type = oracle::bind::binary_double;"
- << b << ".buffer= &" << arg << "." << mi.var << "value;"
- << b << ".capacity = 8;"
- << b << ".size = 0;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_big_float (member_info& mi)
- {
- os << b << ".type = oracle::bind::number;"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".capacity = static_cast<ub4> (sizeof (" << arg << "." <<
- mi.var << "value));"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << b << ".type = oracle::bind::date;"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".capacity = static_cast<ub4> (sizeof (" << arg << "." <<
- mi.var << "value));"
- << b << ".size = 0;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_timestamp (member_info& mi)
- {
- os << b << ".type = oracle::bind::timestamp;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_interval_ym (member_info& mi)
- {
- os << b << ".type = oracle::bind::interval_ym;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_interval_ds (member_info& mi)
- {
- os << b << ".type = oracle::bind::interval_ds;"
- << b << ".buffer = &" << arg << "." << mi.var << "value;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << b << ".type = " <<
- string_buffer_types[mi.st->type - sql_type::CHAR] << ";"
- << b << ".buffer = " << arg << "." << mi.var << "value;"
- << b << ".capacity = static_cast<ub4> (sizeof (" << arg <<
- "." << mi.var << "value));"
- << b << ".size = &" << arg << "." << mi.var << "size;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;";
- }
-
- virtual void
- traverse_lob (member_info& mi)
- {
- os << b << ".type = " <<
- lob_buffer_types[mi.st->type - sql_type::BLOB] << ";"
- << b << ".buffer = &" << arg << "." << mi.var << "lob;"
- << b << ".indicator = &" << arg << "." << mi.var << "indicator;"
- << b << ".callback = &" << arg << "." << mi.var << "callback;"
- << endl;
- }
- };
- entry<bind_member> bind_member_;
-
- //
- // init image
- //
-
- struct init_image_member: relational::init_image_member_impl<sql_type>,
- member_base
- {
- init_image_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- check_accessor (member_info& mi, member_access& ma)
- {
- // We cannot use accessors that return by-value for LOB
- // members.
- //
- if ((mi.st->type == sql_type::BLOB ||
- mi.st->type == sql_type::CLOB ||
- mi.st->type == sql_type::NCLOB) &&
- ma.by_value)
- {
- error (ma.loc) << "accessor returning a value cannot be used "
- << "for a data member of Oracle LOB type" << endl;
- info (ma.loc) << "accessor returning a const reference is required"
- << endl;
- info (mi.m.location ()) << "data member is defined here" << endl;
- throw operation_failed ();
- }
- }
-
- virtual void
- set_null (member_info& mi)
- {
- os << "i." << mi.var << "indicator = -1;";
- }
-
- virtual void
- traverse_int32 (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_int64 (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_big_int (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;"
- << "i." << mi.var << "size = static_cast<ub2> (size);";
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_double (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_big_float (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "sizeof (i." << mi.var << "value)," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;"
- << "i." << mi.var << "size = static_cast<ub2> (size);";
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_timestamp (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_interval_ym (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_interval_ds (member_info& mi)
- {
- os << traits << "::set_image (" << endl
- << "i." << mi.var << "value, is_null, " << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << "std::size_t size (0);"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "value," << endl
- << "sizeof (i." << mi.var << "value)," << endl
- << "size," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;"
- << "i." << mi.var << "size = static_cast<ub2> (size);";
- }
-
- virtual void
- traverse_lob (member_info& mi)
- {
- os << "i." << mi.var << "lob.position = 0;"
- << traits << "::set_image (" << endl
- << "i." << mi.var << "callback.callback.param," << endl
- << "i." << mi.var << "callback.context.param," << endl
- << "is_null," << endl
- << member << ");"
- << "i." << mi.var << "indicator = is_null ? -1 : 0;";
- }
- };
- entry<init_image_member> init_image_member_;
-
- //
- // init value
- //
-
- struct init_value_member: relational::init_value_member_impl<sql_type>,
- member_base
- {
- init_value_member (base const& x)
- : member_base::base (x), // virtual base
- member_base::base_impl (x), // virtual base
- base_impl (x),
- member_base (x)
- {
- }
-
- virtual void
- get_null (string const& var) const
- {
- os << "i." << var << "indicator == -1";
- }
-
- virtual void
- check_modifier (member_info& mi, member_access& ma)
- {
- // We cannot use by-value modifier for LOB members.
- //
- if ((mi.st->type == sql_type::BLOB ||
- mi.st->type == sql_type::CLOB ||
- mi.st->type == sql_type::NCLOB) &&
- ma.placeholder ())
- {
- error (ma.loc) << "modifier accepting a value cannot be used "
- << "for a data member of Oracle LOB type" << endl;
- info (ma.loc) << "modifier returning a non-const reference is "
- << "required" << endl;
- info (mi.m.location ()) << "data member is defined here" << endl;
- throw operation_failed ();
- }
- }
-
- virtual void
- traverse_int32 (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_int64 (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_big_int (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_float (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_double (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_big_float (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_date (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_timestamp (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_interval_ym (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_interval_ds (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_string (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "i." << mi.var << "size," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
-
- virtual void
- traverse_lob (member_info& mi)
- {
- os << traits << "::set_value (" << endl
- << member << "," << endl
- << "i." << mi.var << "callback.callback.result," << endl
- << "i." << mi.var << "callback.context.result," << endl
- << "i." << mi.var << "indicator == -1);"
- << endl;
- }
- };
- entry<init_value_member> init_value_member_;
-
- struct container_traits: relational::container_traits, context
- {
- container_traits (base const& x): base (x) {}
-
- virtual void
- cache_result (string const&)
- {
- // Caching is not necessary since Oracle can execute several
- // interleaving statements.
- //
- }
-
- virtual void
- init_value_extra ()
- {
- os << "sts.select_statement ().stream_result ();"
- << endl;
- }
- };
- entry<container_traits> container_traits_;
-
- struct section_traits: relational::section_traits, context
- {
- section_traits (base const& x): base (x) {}
-
- virtual void
- init_value_extra ()
- {
- os << "st.stream_result ();";
- }
- };
- entry<section_traits> section_traits_;
-
- struct class_: relational::class_, context
- {
- class_ (base const& x): base (x) {}
-
- virtual void
- init_image_pre (type& c)
- {
- if (options.generate_query () &&
- !(composite (c) || (abstract (c) && !polymorphic (c))))
- {
- type* poly_root (polymorphic (c));
- bool poly_derived (poly_root != 0 && poly_root != &c);
-
- if (poly_derived)
- os << "{"
- << "root_traits::image_type& ri (root_image (i));"
- << endl;
-
- string i (poly_derived ? "ri" : "i");
-
- os << "if (" << i << ".change_callback_.callback != 0)" << endl
- << "(" << i << ".change_callback_.callback) (" <<
- i << ".change_callback_.context);";
-
- if (poly_derived)
- os << "}";
- else
- os << endl;
- }
- }
-
- virtual void
- init_value_extra ()
- {
- os << "st.stream_result ();";
- }
-
- virtual string
- persist_statement_extra (type& c,
- relational::query_parameters& qp,
- persist_position p)
- {
- string r;
-
- if (p == persist_after_values)
- {
- data_member_path* id (id_member (c));
-
- type* poly_root (polymorphic (c));
- bool poly_derived (poly_root != 0 && poly_root != &c);
-
- // Top-level auto id.
- //
- if (id != 0 && !poly_derived && auto_ (*id))
- {
- semantics::data_member& idb (*id->back ());
-
- const string& name (column_qname (*id));
- const string& type (column_type (idb));
-
- r = "RETURNING " + convert_from (name, type, idb) +
- " INTO " + qp.next (idb, name, type);
- }
- }
-
- return r;
- }
-
- virtual string
- select_trailer (type& c)
- {
- view_query const& vq (c.get<view_query> ("query"));
-
- if (vq.for_update && vq.distinct)
- {
- error (vq.loc)
- << "Oracle does not support FOR UPDATE with DISTINCT" << endl;
- throw operation_failed ();
- }
-
- return base::select_trailer (c);
- }
- };
- entry<class_> class_entry_;
- }
- }
-}