diff options
Diffstat (limited to 'odb/relational/sqlite')
-rw-r--r-- | odb/relational/sqlite/context.cxx | 66 | ||||
-rw-r--r-- | odb/relational/sqlite/context.hxx | 20 | ||||
-rw-r--r-- | odb/relational/sqlite/model.cxx | 58 | ||||
-rw-r--r-- | odb/relational/sqlite/schema.cxx | 60 |
4 files changed, 121 insertions, 83 deletions
diff --git a/odb/relational/sqlite/context.cxx b/odb/relational/sqlite/context.cxx index 466c5b9..a769fac 100644 --- a/odb/relational/sqlite/context.cxx +++ b/odb/relational/sqlite/context.cxx @@ -65,16 +65,19 @@ namespace relational } context:: - context (ostream& os, semantics::unit& u, options_type const& ops) + context (ostream& os, + semantics::unit& u, + options_type const& ops, + sema_rel::model* m) : root_context (os, u, ops, data_ptr (new (shared) data (os))), - base_context (static_cast<data*> (root_context::data_.get ())), + base_context (static_cast<data*> (root_context::data_.get ()), m), data_ (static_cast<data*> (base_context::data_)) { assert (current_ == 0); current_ = this; - data_->generate_grow_ = true; - data_->need_alias_as_ = true; + generate_grow = true; + need_alias_as = true; data_->bind_vector_ = "sqlite::bind*"; data_->truncated_vector_ = "bool*"; @@ -222,8 +225,8 @@ namespace relational { struct sql_parser { - sql_parser (semantics::data_member& m, std::string const& sql) - : m_ (m), l_ (sql) + sql_parser (std::string const& sql) + : l_ (sql) { } @@ -269,27 +272,20 @@ namespace relational } else { - cerr << m_.file () << ":" << m_.line () << ":" << m_.column () - << ": error: expected SQLite type name instead of '" - << t << "'" << endl; - throw operation_failed (); + throw context::invalid_sql_type ( + "expected SQLite type name instead of '" + t.string () + + "'"); } } } catch (sql_lexer::invalid_input const& e) { - cerr << m_.file () << ":" << m_.line () << ":" << m_.column () - << ": error: invalid SQLite type declaration: " << e.message - << endl; - throw operation_failed (); + throw context::invalid_sql_type ( + "invalid SQLite type declaration: " + e.message); } if (ids_.empty ()) - { - cerr << m_.file () << ":" << m_.line () << ":" << m_.column () - << ": error: expected SQLite type name" << endl; - throw operation_failed (); - } + throw context::invalid_sql_type ("expected SQLite type name"); sql_type r; @@ -322,9 +318,8 @@ namespace relational r.type = sql_type::TEXT; else { - cerr << m_.file () << ":" << m_.line () << ":" << m_.column () - << " error: unknown SQLite type '" << id << "'" << endl; - throw operation_failed (); + throw context::invalid_sql_type ( + "unknown SQLite type '" + id + "'"); } } @@ -343,10 +338,8 @@ namespace relational if (t.type () == sql_token::t_eos) { - cerr << m_.file () << ":" << m_.line () << ":" << m_.column () - << ": error: missing ')' in SQLite type declaration" - << endl; - throw operation_failed (); + throw context::invalid_sql_type ( + "missing ')' in SQLite type declaration"); } } } @@ -368,7 +361,6 @@ namespace relational typedef vector<string> identifiers; private: - semantics::data_member& m_; sql_lexer l_; identifiers ids_; }; @@ -383,11 +375,27 @@ namespace relational if (!m.count (key)) { - sql_parser p (m, column_type (m, kp)); - m.set (key, p.parse ()); + try + { + m.set (key, parse_sql_type (column_type (m, kp))); + } + catch (invalid_sql_type const& e) + { + cerr << m.file () << ":" << m.line () << ":" << m.column () + << ": error: " << e.message () << endl; + + throw operation_failed (); + } } return m.get<sql_type> (key); } + + sql_type context:: + parse_sql_type (string const& t) + { + sql_parser p (t); + return p.parse (); + } } } diff --git a/odb/relational/sqlite/context.hxx b/odb/relational/sqlite/context.hxx index b5c3d85..de4e4c7 100644 --- a/odb/relational/sqlite/context.hxx +++ b/odb/relational/sqlite/context.hxx @@ -37,6 +37,21 @@ namespace relational column_sql_type (semantics::data_member&, string const& key_prefix = string ()); + public: + struct invalid_sql_type + { + invalid_sql_type (string const& message): message_ (message) {} + + string const& + message () const {return message_;} + + private: + string message_; + }; + + static sql_type + parse_sql_type (string const&); + protected: virtual bool grow_impl (semantics::class_&); @@ -55,7 +70,10 @@ namespace relational virtual ~context (); context (); - context (std::ostream&, semantics::unit&, options_type const&); + context (std::ostream&, + semantics::unit&, + options_type const&, + sema_rel::model*); static context& current () diff --git a/odb/relational/sqlite/model.cxx b/odb/relational/sqlite/model.cxx new file mode 100644 index 0000000..1324255 --- /dev/null +++ b/odb/relational/sqlite/model.cxx @@ -0,0 +1,58 @@ +// file : odb/relational/sqlite/model.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC +// license : GNU GPL v3; see accompanying LICENSE file + +#include <sstream> + +#include <odb/relational/model.hxx> + +#include <odb/relational/sqlite/common.hxx> +#include <odb/relational/sqlite/context.hxx> + +using namespace std; + +namespace relational +{ + namespace sqlite + { + 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 INTEGER. + // + if (column_sql_type (m).type != sql_type::INTEGER) + { + cerr << m.file () << ":" << m.line () << ":" << m.column () + << ": error: column with default value specified as C++ " + << "enumerator must map to SQLite INTEGER" << 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 (); + } + }; + entry<object_columns> object_columns_; + } + } +} diff --git a/odb/relational/sqlite/schema.cxx b/odb/relational/sqlite/schema.cxx index 589ce7b..6562905 100644 --- a/odb/relational/sqlite/schema.cxx +++ b/odb/relational/sqlite/schema.cxx @@ -20,66 +20,20 @@ namespace relational // Create. // - struct object_columns: relational::object_columns, context + struct create_column: relational::create_column, context { - object_columns (base const& x): base (x) {} + create_column (base const& x): base (x) {} virtual void - default_enum (semantics::data_member& m, tree en, string const&) + auto_ (sema_rel::column&) { - // Make sure the column is mapped to INTEGER. - // - if (column_sql_type (m).type != sql_type::INTEGER) - { - cerr << m.file () << ":" << m.line () << ":" << m.column () - << ": error: column with default value specified as C++ " - << "enumerator must map to SQLite INTEGER" << endl; - - throw operation_failed (); - } - - using semantics::enumerator; - - enumerator& e (dynamic_cast<enumerator&> (*unit.find (en))); - - if (e.enum_ ().unsigned_ ()) - os << " DEFAULT " << e.value (); + if (options.sqlite_lax_auto_id ()) + os << " /*AUTOINCREMENT*/"; else - os << " DEFAULT " << static_cast<long long> (e.value ()); + os << " AUTOINCREMENT"; } - - virtual void - constraints (semantics::data_member& m) - { - base::constraints (m); - - if (m.count ("auto")) - { - if (options.sqlite_lax_auto_id ()) - os << " /*AUTOINCREMENT*/"; - else - os << " AUTOINCREMENT"; - } - } - - virtual void - reference (semantics::data_member& m) - { - // In SQLite, by default, constraints are immediate. - // - if (semantics::class_* c = - object_pointer (member_utype (m, prefix_))) - { - os << " REFERENCES " << table_qname (*c) << " (" << - column_qname (*id_member (*c)) << ") " << - "DEFERRABLE INITIALLY DEFERRED"; - } - else - base::reference (m); - } - }; - entry<object_columns> object_columns_; + entry<create_column> create_column_; } } } |