Skip to content

Commit 5baa532

Browse files
committed
上传
1 parent 3470f94 commit 5baa532

File tree

6 files changed

+224974
-0
lines changed

6 files changed

+224974
-0
lines changed

include/sqlite/sqlite.hpp

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#pragma once
2+
/*
3+
* Covariant Script Sqlite
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as published
7+
* by the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*
18+
* Copyright (C) 2017 Michael Lee(李登淳)
19+
* Email: mikecovlee@163.com
20+
* Github: https://github.com/mikecovlee
21+
*/
22+
#include <covscript/exceptions.hpp>
23+
#include "sqlite3.h"
24+
#include "sqlite3.c"
25+
#include <utility>
26+
#include <string>
27+
#include <memory>
28+
29+
namespace cs_impl {
30+
class sqlite final {
31+
class db_holder final {
32+
public:
33+
::sqlite3 *db;
34+
35+
db_holder()
36+
{
37+
if (::sqlite3_open(":memory:", &db) != SQLITE_OK)
38+
throw cs::lang_error(::sqlite3_errmsg(db));
39+
}
40+
41+
explicit db_holder(const char *path)
42+
{
43+
if (::sqlite3_open(path, &db) != SQLITE_OK)
44+
throw cs::lang_error(::sqlite3_errmsg(db));
45+
}
46+
47+
db_holder(const db_holder &) = delete;
48+
49+
~db_holder()
50+
{
51+
::sqlite3_close(db);
52+
}
53+
};
54+
55+
class stmt_holder final {
56+
public:
57+
int errcode = SQLITE_OK;
58+
59+
::sqlite3 *host;
60+
61+
::sqlite3_stmt *stmt;
62+
63+
stmt_holder() = delete;
64+
65+
explicit stmt_holder(::sqlite3 *db, const char *sql, std::size_t len) : host(db)
66+
{
67+
if (::sqlite3_prepare_v2(host, sql, len, &stmt, nullptr) != SQLITE_OK)
68+
throw cs::lang_error(::sqlite3_errmsg(db));
69+
}
70+
71+
stmt_holder(const stmt_holder &) = delete;
72+
73+
~stmt_holder()
74+
{
75+
::sqlite3_finalize(stmt);
76+
}
77+
};
78+
79+
std::shared_ptr<db_holder> m_db;
80+
public:
81+
enum class data_type {
82+
integer, real, text
83+
};
84+
85+
class statement final {
86+
friend class sqlite;
87+
88+
std::shared_ptr<stmt_holder> m_stmt;
89+
90+
explicit statement(const std::shared_ptr<db_holder> &db, const std::string &sql) : m_stmt(
91+
std::make_shared<stmt_holder>(db->db, sql.c_str(), sql.size())) {}
92+
93+
public:
94+
statement() = delete;
95+
96+
statement(const statement &) = default;
97+
98+
~statement() = default;
99+
100+
bool done() const
101+
{
102+
return m_stmt->errcode == SQLITE_DONE;
103+
}
104+
105+
void reset()
106+
{
107+
if (::sqlite3_reset(m_stmt->stmt) != SQLITE_OK)
108+
throw cs::lang_error(::sqlite3_errmsg(m_stmt->host));
109+
}
110+
111+
void step()
112+
{
113+
if ((m_stmt->errcode = ::sqlite3_step(m_stmt->stmt)) == SQLITE_ERROR)
114+
throw cs::lang_error(::sqlite3_errmsg(m_stmt->host));
115+
}
116+
117+
std::size_t column_count() const
118+
{
119+
return ::sqlite3_column_count(m_stmt->stmt);
120+
}
121+
122+
data_type column_type(std::size_t index) const
123+
{
124+
switch (::sqlite3_column_type(m_stmt->stmt, index)) {
125+
case SQLITE_INTEGER:
126+
return data_type::integer;
127+
case SQLITE_FLOAT:
128+
return data_type::real;
129+
case SQLITE_TEXT:
130+
return data_type::text;
131+
default:
132+
throw cs::lang_error("Unsupported type.");
133+
}
134+
}
135+
136+
std::string column_name(std::size_t index) const
137+
{
138+
return ::sqlite3_column_name(m_stmt->stmt, index);
139+
}
140+
141+
std::string column_decltype(std::size_t index) const
142+
{
143+
return ::sqlite3_column_decltype(m_stmt->stmt, index);
144+
}
145+
146+
int column_integer(std::size_t index) const
147+
{
148+
return ::sqlite3_column_int(m_stmt->stmt, index);
149+
}
150+
151+
double column_real(std::size_t index) const
152+
{
153+
return ::sqlite3_column_double(m_stmt->stmt, index);
154+
}
155+
156+
std::string column_text(std::size_t index) const
157+
{
158+
return reinterpret_cast<const char *>(::sqlite3_column_text(m_stmt->stmt, index));
159+
}
160+
161+
std::size_t bind_param_count() const
162+
{
163+
return ::sqlite3_bind_parameter_count(m_stmt->stmt);
164+
}
165+
166+
void bind_integer(std::size_t index, int data)
167+
{
168+
if (::sqlite3_bind_int(m_stmt->stmt, index, data) != SQLITE_OK)
169+
throw cs::lang_error(::sqlite3_errmsg(m_stmt->host));
170+
}
171+
172+
void bind_real(std::size_t index, double data)
173+
{
174+
if (::sqlite3_bind_double(m_stmt->stmt, index, data) != SQLITE_OK)
175+
throw cs::lang_error(::sqlite3_errmsg(m_stmt->host));
176+
}
177+
178+
void bind_text(std::size_t index, const std::string &data)
179+
{
180+
if (::sqlite3_bind_text(m_stmt->stmt, index, data.c_str(), data.size(), nullptr) != SQLITE_OK)
181+
throw cs::lang_error(::sqlite3_errmsg(m_stmt->host));
182+
}
183+
184+
void clear_bindings()
185+
{
186+
::sqlite3_clear_bindings(m_stmt->stmt);
187+
}
188+
};
189+
190+
sqlite() : m_db(std::make_shared<db_holder>()) {}
191+
192+
explicit sqlite(const std::string &path) : m_db(std::make_shared<db_holder>(path.c_str())) {}
193+
194+
sqlite(const sqlite &) = default;
195+
196+
~sqlite() = default;
197+
198+
statement prepare(const std::string &sql)
199+
{
200+
return statement(m_db, sql);
201+
}
202+
};
203+
}

0 commit comments

Comments
 (0)