aboutsummaryrefslogtreecommitdiff
path: root/odb/relational/mysql/schema.cxx
blob: 5866df18644defbdc2d7317d0e53720c03c58ef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// file      : odb/relational/mysql/schema.cxx
// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
// license   : GNU GPL v3; see accompanying LICENSE file

#include <odb/relational/schema.hxx>

#include <odb/relational/mysql/common.hxx>
#include <odb/relational/mysql/context.hxx>

namespace relational
{
  namespace mysql
  {
    namespace schema
    {
      namespace relational = relational::schema;

      //
      // Create.
      //

      struct create_column: relational::create_column, context
      {
        create_column (base const& x): base (x) {}

        virtual void
        null (sema_rel::column& c)
        {
          // MySQL TIMESTAMP is by default NOT NULL. If we want it
          // to contain NULL values, we need to explicitly declare
          // the column as NULL.
          //
          if (c.null ())
          {
            // This should never fail since we have already parsed this.
            //
            sql_type const& t (parse_sql_type (c.type ()));

            if (t.type == sql_type::TIMESTAMP)
            {
              os << " NULL";
              return;
            }
          }

          base::null (c);
        }

        virtual void
        auto_ (sema_rel::column&)
        {
          os << " AUTO_INCREMENT";
        }
      };
      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 (sema_rel::foreign_key& fk)
        {
          // MySQL does not support deferred constraint checking. Output
          // such foreign keys as comments, for documentation, unless we
          // are generating embedded schema.
          //
          if (fk.deferred ())
          {
            // Don't bloat C++ code with comment strings if we are
            // generating embedded schema.
            //
            if (format_ != schema_format::embedded)
            {
              os << endl
                 << endl
                 << "  /*" << endl;

              base::create (fk);

              os << endl
                 << "  */";
            }
          }
          else
            base::traverse (fk);
        }

        virtual string
        name (sema_rel::foreign_key& fk)
        {
          // In MySQL, foreign key names are database-global. Make them
          // unique by prefixing the key name with table name. Note,
          // however, that they cannot be prefixed with the database name.
          //
          return quote_id (
            static_cast<sema_rel::table&> (fk.scope ()).name ().uname ()
            + "_" + fk.name ());
        }

        virtual void
        deferred ()
        {
          // MySQL doesn't support deferred.
        }
      };
      entry<create_foreign_key> create_foreign_key_;

      struct create_table: relational::create_table, context
      {
        create_table (base const& x): base (x) {}

        virtual void
        create_post ()
        {
          os << ")";

          string const& engine (options.mysql_engine ());

          if (engine != "default")
            os << endl
               << " ENGINE=" << engine;

          os << endl;
        }
      };
      entry<create_table> create_table_;

      struct create_index: relational::create_index, context
      {
        create_index (base const& x): base (x) {}

        virtual string
        name (sema_rel::index& in)
        {
          // In MySQL an index cannot be qualified with the database name.
          //
          return quote_id (in.name ().uname ());
        }
      };
      entry<create_index> create_index_;
    }
  }
}