File: SQLite.h

package info (click to toggle)
glgrib 1.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,861,496 kB
  • sloc: cpp: 20,811; ansic: 6,530; perl: 2,902; sh: 513; makefile: 147; python: 58; sql: 18
file content (169 lines) | stat: -rw-r--r-- 3,923 bytes parent folder | download | duplicates (2)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#pragma once

#include <sqlite3.h>
#include <string>
#include <iostream>
#include <list>
#include <exception>
#include <memory>


namespace glGrib
{

namespace SQLiteDetail
{

  class _sqlite3
  {
  public:
    ~_sqlite3 () 
    {
      if (data != nullptr)
        sqlite3_close (data);
      data = nullptr;
    }
    sqlite3 * data = nullptr;
  };

  typedef std::shared_ptr<_sqlite3> sqlite3_ptr;

  class _sqlite3_stmt
  {
  public:
    ~_sqlite3_stmt () 
    {
      if (data != nullptr)
        sqlite3_finalize (data);
      data = nullptr;
    }
    sqlite3_stmt * data = nullptr;
  };

  typedef std::shared_ptr<_sqlite3_stmt> sqlite3_stmt_ptr;

  void ok (sqlite3_ptr db, int rc);

  void iset (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, const long int * t);
  void iset (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, const int * t);
  void iset (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, const float * t);
  void iset (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, const char * t);
  void iset (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, const std::string * t);

  void isetList (sqlite3_ptr, sqlite3_stmt_ptr, int);
  template <typename T, typename... Types>
  void isetList (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, const T & t, Types... args)
  {
    iset (db, req, rank, t);
    isetList (db, req, rank + 1, args...);
  }

  void oget (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, int * t);
  void oget (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, float * t);
  void oget (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, char * t);
  void oget (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, std::string * t);

  void ogetList (sqlite3_ptr, sqlite3_stmt_ptr, int);
  template <typename T, typename... Types>
  void ogetList (sqlite3_ptr db, sqlite3_stmt_ptr req, int rank, T t, Types... args)
  {
    if (rank >= sqlite3_column_count (req->data))
      throw std::runtime_error (std::string ("Column out of bounds"));
    oget (db, req, rank, t);
    ogetList (db, req, rank + 1, args...);
  }

};

class SQLite
{
public:

  typedef SQLiteDetail::sqlite3_ptr sqlite3_ptr;
  typedef SQLiteDetail::sqlite3_stmt_ptr sqlite3_stmt_ptr;

  explicit SQLite (const std::string & file)
  {
    db = std::make_shared<SQLiteDetail::_sqlite3>();
    if (sqlite3_open (file.c_str (), &db->data) != SQLITE_OK)
      throw std::runtime_error (std::string ("Cannot open database ") + file);
  }

  class stmt
  {
  public:
    
    stmt ()
    {
      req = std::make_shared<SQLiteDetail::_sqlite3_stmt>();
    }
    ~stmt ()
    {
    }
    void reset ()
    {
      SQLiteDetail::ok (db, sqlite3_reset (req->data));
    }
    template <typename... Types>
    void bindall (Types... args)
    {
      SQLiteDetail::isetList (db, req, 0, args...);
    }
    template <typename... Types>
    void execute (Types... args)
    {
      bindall (args...);
      sqlite3_step (req->data);
    }
    template <typename... Types>
    bool fetchRow (Types... args)
    {
      if (sqlite3_step (req->data) == SQLITE_ROW)
        {
          SQLiteDetail::ogetList (db, req, 0, args...);
          return true;
	}
      return false;
    }
    template <typename T>
    void bind (int rank, const T * t)
    {
      if (rank >= sqlite3_bind_parameter_count (req->data))
        throw std::runtime_error (std::string ("Column out of bounds"));
      SQLiteDetail::iset (db, req, rank, t);
    }
  private:
    sqlite3_stmt_ptr req;
    sqlite3_ptr db;
    friend class SQLite;
  };

  const stmt prepare (const std::string & sql)
  {
    stmt st;
    st.db = db;
    SQLiteDetail::ok (db, sqlite3_prepare_v2 (db->data, sql.c_str (), -1, &st.req->data, 0));
    return st;
  }

  void execute (const std::string & sql)
  {
    SQLiteDetail::ok (db, sqlite3_exec (db->data, sql.c_str (), 0, 0, 0));
  }

  ~SQLite ()
  {
    close ();
  }

  void close () 
  {
  }

private:
  sqlite3_ptr db;
};



}