aboutsummaryrefslogtreecommitdiff
path: root/odb/relational/model.cxx
blob: 6b8db1bf5e418b6a22993b488049f348d4d04929 (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
// file      : odb/relational/model.cxx
// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC
// license   : GNU GPL v3; see accompanying LICENSE file

#include <odb/diagnostics.hxx>

#include <odb/relational/model.hxx>
#include <odb/relational/generate.hxx>

using namespace std;

namespace relational
{
  namespace model
  {
    // object_columns
    //
    string object_columns::
    default_ (semantics::data_member& m)
    {
      default_value* dv (0);

      semantics::type& t (utype (m));

      if (m.count ("default"))
        dv = &m.get<default_value> ("default");
      else if (t.count ("default"))
        dv = &t.get<default_value> ("default");
      else
        return ""; // No default value for this column.

      switch (dv->kind)
      {
      case default_value::reset:
        {
          return ""; // No default value.
        }
      case default_value::null:
        {
          return default_null (m);
        }
      case default_value::boolean:
        {
          return default_bool (m, dv->literal == "true");
        }
      case default_value::integer:
        {
          return default_integer (m, dv->int_value, dv->literal == "-");
        }
      case default_value::floating:
        {
          return default_float (m, dv->float_value);
        }
      case default_value::string:
        {
          return default_string (m, dv->literal);
        }
      case default_value::enumerator:
        {
          return default_enum (m, dv->enum_value, dv->literal);
        }
      }

      return "";
    }

    cutl::shared_ptr<sema_rel::model>
    generate ()
    {
      context ctx;
      cutl::shared_ptr<sema_rel::model> m (new (shared) sema_rel::model);

      traversal::unit unit;
      traversal::defines unit_defines;
      typedefs unit_typedefs (false);
      traversal::namespace_ ns;
      instance<class_> c (*m);

      unit >> unit_defines >> ns;
      unit_defines >> c;
      unit >> unit_typedefs >> c;

      traversal::defines ns_defines;
      typedefs ns_typedefs (false);

      ns >> ns_defines >> ns;
      ns_defines >> c;
      ns >> ns_typedefs >> c;

      try
      {
        unit.dispatch (ctx.unit);
      }
      catch (sema_rel::duplicate_name const& e)
      {
        location const& o (e.orig.get<location> ("cxx-location"));
        location const& d (e.dup.get<location> ("cxx-location"));

        error (d) << e.dup.kind () << " name '" << e.name << "' conflicts "
                  << "with an already defined " << e.orig.kind () << " name"
                  << endl;

        info (o) << "conflicting " << e.orig.kind () << " is defined here"
                 << endl;

        if (e.dup.kind () == "index")
          error (d) << "use #pragma db index to change one of the names"
                    << endl;
        else if (e.dup.kind () == "table")
          error (d) << "use #pragma db table to change one of the names"
                    << endl;
        else
          error (d) << "use #pragma db column to change its name"
                    << endl;

        throw operation_failed ();
      }

      return m;
    }
  }
}