master
ブランチ master
cpputils / src / sqlitepp / sqlitepp.cc
6.3 KB、214行 生 Blame 履歴
1/*
2# 076 Free License
3
4Copyright (c) テクニカル諏訪子
5
6Permission is hereby granted to any person obtaining a copy of the software
7C++ Utils (the "Software") to use, modify, merge, copy, publish, distribute,
8sublicense, and/or sell copies of the Software, subject to the following conditions:
9
10 1. **Origin Attribution**:
11 - You must not misrepresent the origin of the Software; you must not claim
12 you created the original Software.
13 2. **Notice Preservation**:
14 - This license and the above copyright notice must remain intact in all copies
15 of the source code.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*/
24#include <sqlitepp/sqlitepp.hh>
25#include <sqlite3.h>
26#include <iostream>
27#include <stdexcept>
28#include <filesystem>
29
30#if defined(WIN32) || defined(WIN64)
31#ifndef WIN32_LEAN_AND_MEAN
32#define WIN32_LEAN_AND_MEAN
33#endif
34#include <windows.h>
35#include <shlobj.h>
36
37std::filesystem::path GetLocalAppDataPath() {
38 PWSTR path = nullptr;
39 HRESULT hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &path);
40 if (FAILED(hr)) throw std::runtime_error("LocalAppDataパスの受取の失敗。");
41
42 std::filesystem::path p(path);
43 CoTaskMemFree(path);
44
45 return p;
46}
47#endif
48
49std::filesystem::path GetUserDataPath() {
50#if defined(WIN32) || defined(WIN64)
51 return GetLocalAppDataPath() / "076Studio" / "ShaderPlayground";
52#elif defined(__APPLE__)
53 cstr home = std::getenv("HOME");
54 if (!home) throw std::runtime_error("HOME環境変数がありません。");
55
56 return std::filesystem::path(home) / "Library" / "Application Support" / "ShaderPlayground";
57#else
58 cstr xdg = std::getenv("XDG_DATA_HOME");
59 if (xdg) return std::filesystem::path(xdg) / "shaderplayground";
60
61 cstr home = std::getenv("HOME");
62 if (!home) throw std::runtime_error("HOME環境変数がありません。");
63
64 return std::filesystem::path(home) / ".local" / "share" / "shaderplayground";
65#endif
66}
67
68namespace sqlitepp {
69 Instance::Instance() {
70 m_pDB = nullptr;
71#ifdef PRODUCTION_BUILD
72 std::filesystem::path dbPath = GetUserDataPath() / "shaderplayground.db";
73 if (!std::filesystem::exists(std::filesystem::path(dbPath).parent_path())) {
74 std::filesystem::create_directories(std::filesystem::path(dbPath).parent_path());
75 }
76
77 if (sqlite3_open(dbPath.string().c_str(), &m_pDB) != SQLITE_OK) {
78#else
79 constexpr std::string_view DB_PATH = DB_NAME;
80 if (sqlite3_open(DB_PATH.data(), &m_pDB) != SQLITE_OK) {
81#endif
82 throw std::runtime_error("SQLiteデータベースを開けられません。");
83 }
84 }
85
86 Instance::~Instance() {
87 sqlite3_close(m_pDB);
88 }
89
90 bool Instance::Exec(string sql) {
91 char *err = nullptr;
92 bool suc = sqlite3_exec(m_pDB, sql.c_str(), nullptr, nullptr, &err);
93 if (suc != SQLITE_OK) {
94 std::cerr << "データ実行に失敗:" << err << std::endl;
95 sqlite3_free(err);
96 return false;
97 }
98
99 return true;
100 }
101
102 i64 Instance::GetLastInsertId() {
103 return sqlite3_last_insert_rowid(m_pDB);
104 }
105
106 ///////////////////
107
108 Stmt::Stmt(sqlite3 *pDB) {
109 m_pDB = pDB;
110 }
111
112 Stmt::~Stmt() {
113 sqlite3_finalize(m_pSTMT);
114 }
115
116 bool Stmt::Prepare(const std::string &sql) {
117 if (sqlite3_prepare_v2(m_pDB, sql.c_str(), static_cast<int>(sql.size() + 1), &m_pSTMT, nullptr) != SQLITE_OK) {
118 throw std::runtime_error("SQLの準備に失敗: " + std::string(sqlite3_errmsg(m_pDB)));
119 }
120
121 return true;
122 }
123
124
125 bool Stmt::BindBlob(int index, any data, u32 size) {
126 return sqlite3_bind_blob(m_pSTMT, index, data, size, SQLITE_TRANSIENT);
127 }
128
129 bool Stmt::BindBlob64(int index, any data, u64 size) {
130 return sqlite3_bind_blob64(m_pSTMT, index, data, size, SQLITE_TRANSIENT);
131 }
132
133 bool Stmt::BindDouble(int index, f64 data) {
134 return sqlite3_bind_double(m_pSTMT, index, data);
135 }
136
137 bool Stmt::BindInt(int index, i32 data) {
138 return sqlite3_bind_int(m_pSTMT, index, data);
139 }
140
141 bool Stmt::BindInt64(int index, i64 data) {
142 return sqlite3_bind_int64(m_pSTMT, index, data);
143 }
144
145 bool Stmt::BindNull(int index) {
146 return sqlite3_bind_null(m_pSTMT, index);
147 }
148
149 bool Stmt::BindText(int index, const string &data) {
150 if (data.empty()) {
151 return sqlite3_bind_text(m_pSTMT, index, "", 0, SQLITE_TRANSIENT) == SQLITE_OK;
152 }
153 return sqlite3_bind_text(m_pSTMT, index,
154 data.c_str(),
155 static_cast<int>(data.size()),
156 SQLITE_TRANSIENT) == SQLITE_OK;
157 }
158
159 bool Stmt::BindText16(int index, const string &data) {
160 return sqlite3_bind_text16(m_pSTMT, index, data.c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK;
161 }
162
163 bool Stmt::BindText64(int index, const string &data) {
164 return sqlite3_bind_text64(m_pSTMT, index, data.c_str(), data.size(), SQLITE_TRANSIENT, SQLITE_UTF8) == SQLITE_OK;
165 }
166
167 const void *Stmt::ColumnBlob(int col) {
168 return sqlite3_column_blob(m_pSTMT, col);
169 }
170
171 f64 Stmt::ColumnDouble(int col) {
172 return sqlite3_column_double(m_pSTMT, col);
173 }
174
175 int Stmt::ColumnInt(int col) {
176 return sqlite3_column_int(m_pSTMT, col);;
177 }
178
179 i64 Stmt::ColumnInt64(int col) {
180 return sqlite3_column_int64(m_pSTMT, col);
181 }
182
183 string Stmt::ColumnText(int col) {
184 const unsigned char *text = sqlite3_column_text(m_pSTMT, col);
185 if (text == nullptr) return "";
186 int len = sqlite3_column_bytes(m_pSTMT, col);
187 return std::string(reinterpret_cast<const char *>(text), len);
188 }
189
190 //const any Stmt::ColumnText16(int col) {
191 // return sqlite3_column_text16(m_pSTMT, col);
192 //}
193
194 sqlite3_value *Stmt::ColumnValue(int col) {
195 return sqlite3_column_value(m_pSTMT, col);
196 }
197
198 int Stmt::ColumnBytes(int col) {
199 return sqlite3_column_bytes(m_pSTMT, col);
200 }
201
202 int Stmt::ColumnBytes16(int col) {
203 return sqlite3_column_bytes16(m_pSTMT, col);
204 }
205
206 int Stmt::ColumnType(int col) {
207 return sqlite3_column_type(m_pSTMT, col);
208 }
209
210
211 int Stmt::Step() {
212 return sqlite3_step(m_pSTMT);
213 }
214} // namespace sqlitepp