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

#ifndef ODB_OPTION_PARSERS_HXX
#define ODB_OPTION_PARSERS_HXX

#include <sstream>

#include <odb/option-types.hxx>
#include <odb/options.hxx>

namespace cli
{
  template <typename V>
  struct parser<database_map<V> >
  {
    static void
    parse (database_map<V>& m, bool& xs, scanner& s)
    {
      typedef database_map<V> map;

      xs = true;
      std::string o (s.next ());

      if (s.more ())
      {
        std::string ov (s.next ());
        std::string::size_type p = ov.find (':');

        if (p != std::string::npos)
        {
          std::string kstr (ov, 0, p);
          std::string vstr (ov, p + 1);

          // See if this prefix resolves to the database name. If not,
          // assume there is no prefix.
          //
          database k;
          std::istringstream ks (kstr);

          if (ks >> k && ks.eof ())
          {
            V v = V ();

            if (!vstr.empty ())
            {
              std::istringstream vs (vstr);

              if (!(vs >> v && vs.eof ()))
                throw invalid_value (o, ov);
            }

            m[k] = v; // Override any old value.
            return;
          }
        }

        // No database prefix is specified which means it applies to
        // all the databases.
        //
        V v = V ();

        if (!ov.empty ())
        {
          std::istringstream vs (ov);

          if (!(vs >> v && vs.eof ()))
            throw invalid_value (o, ov);
        }

        // We don't want to override database-specific values, so use
        // insert().
        //
        m.insert (typename map::value_type (database::common, v));
        m.insert (typename map::value_type (database::mssql, v));
        m.insert (typename map::value_type (database::mysql, v));
        m.insert (typename map::value_type (database::oracle, v));
        m.insert (typename map::value_type (database::pgsql, v));
        m.insert (typename map::value_type (database::sqlite, v));
      }
      else
        throw missing_value (o);
    }
  };
}


#endif // ODB_OPTION_PARSERS_HXX