23 #ifndef __GNC_DBISQLPROVIDERIMPL_HPP__ 24 #define __GNC_DBISQLPROVIDERIMPL_HPP__ 32 #include "gnc-backend-dbi.hpp" 33 #include "gnc-dbiprovider.hpp" 35 #include <gnc-sql-column-table-entry.hpp> 37 using StrVec = std::vector<std::string>;
43 StrVec get_table_list(dbi_conn conn,
const std::string&
table);
45 StrVec get_index_list (dbi_conn conn);
46 void drop_index(dbi_conn conn,
const std::string& index);
49 template <DbType T> GncDbiProviderPtr
59 const char* type_name =
nullptr;
61 if (info.m_type == BCT_INT)
63 type_name =
"integer";
65 else if (info.m_type == BCT_INT64)
69 else if (info.m_type == BCT_DOUBLE)
73 else if (info.m_type == BCT_STRING || info.m_type == BCT_DATE
74 || info.m_type == BCT_DATETIME)
80 PERR (
"Unknown column type: %d\n", info.m_type);
83 ddl += (info.m_name +
" " + type_name);
86 ddl +=
"(" + std::to_string(info.m_size) +
")";
88 if (info.m_primary_key)
90 ddl +=
" PRIMARY KEY";
94 ddl +=
" AUTOINCREMENT";
107 const char* type_name =
nullptr;
109 if (info.m_type == BCT_INT)
111 type_name =
"integer";
113 else if (info.m_type == BCT_INT64)
115 type_name =
"bigint";
117 else if (info.m_type == BCT_DOUBLE)
119 type_name =
"double";
121 else if (info.m_type == BCT_STRING)
123 type_name =
"varchar";
125 else if (info.m_type == BCT_DATE)
129 else if (info.m_type == BCT_DATETIME)
131 type_name =
"DATETIME NULL DEFAULT '1970-01-01 00:00:00'";
135 PERR (
"Unknown column type: %d\n", info.m_type);
138 ddl += info.m_name +
" " + type_name;
139 if (info.m_size != 0 && info.m_type == BCT_STRING)
141 ddl +=
"(" + std::to_string(info.m_size) +
")";
145 ddl +=
" CHARACTER SET utf8";
147 if (info.m_primary_key)
149 ddl +=
" PRIMARY KEY";
153 ddl +=
" AUTO_INCREMENT";
166 const char* type_name =
nullptr;
168 if (info.m_type == BCT_INT)
172 type_name =
"serial";
176 type_name =
"integer";
179 else if (info.m_type == BCT_INT64)
183 else if (info.m_type == BCT_DOUBLE)
186 type_name =
"double precision";
188 else if (info.m_type == BCT_STRING)
190 type_name =
"varchar";
192 else if (info.m_type == BCT_DATE)
196 else if (info.m_type == BCT_DATETIME)
198 type_name =
"timestamp without time zone";
202 PERR (
"Unknown column type: %d\n", info.m_type);
205 ddl += info.m_name +
" " + type_name;
206 if (info.m_size != 0 && info.m_type == BCT_STRING)
208 ddl +=
"(" + std::to_string(info.m_size) +
")";
210 if (info.m_primary_key)
212 ddl +=
" PRIMARY KEY";
221 conn_get_table_list (dbi_conn conn,
const std::string& dbname,
222 const std::string&
table)
225 const char* tableptr = (
table.empty() ? nullptr :
table.c_str());
226 auto tables = dbi_conn_get_table_list (conn, dbname.c_str(), tableptr);
227 while (dbi_result_next_row (tables) != 0)
229 std::string table_name {dbi_result_get_string_idx (tables, 1)};
230 retval.push_back(table_name);
232 dbi_result_free (tables);
238 const std::string&
table)
242 std::string dbname (dbi_conn_get_option (conn,
"dbname"));
243 auto list = conn_get_table_list (conn, dbname,
table);
244 auto end = std::remove(list.begin(), list.end(),
"sqlite_sequence");
245 list.erase(end, list.end());
251 const std::string&
table)
253 std::string dbname (dbi_conn_get_option (conn,
"dbname"));
254 dbname.insert((std::string::size_type)0, 1,
'`');
256 return conn_get_table_list (conn, dbname,
table);
261 const std::string&
table)
263 const char* query_no_regex =
"SELECT relname FROM pg_class WHERE relname" 264 "!~ '^(pg|sql)_' AND relkind = 'r' ORDER BY relname";
265 std::string query_with_regex =
"SELECT relname FROM pg_class WHERE relname LIKE '";
266 query_with_regex +=
table +
"' AND relkind = 'r' ORDER BY relname";
269 result = dbi_conn_query (conn, query_no_regex);
271 result = dbi_conn_query (conn, query_with_regex.c_str());
275 if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE)
277 PWARN (
"Table List Retrieval Error: %s\n", errmsg);
281 while (dbi_result_next_row (result) != 0)
283 std::string index_name {dbi_result_get_string_idx (result, 1)};
284 list.push_back(index_name);
286 dbi_result_free (result);
295 dbi_result result = dbi_conn_query (conn,
296 "SELECT name FROM sqlite_master WHERE type = 'index' AND name NOT LIKE 'sqlite_autoindex%'");
297 if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE)
299 PWARN (
"Index Table Retrieval Error: %s\n", errmsg);
302 while (dbi_result_next_row (result) != 0)
304 std::string index_name {dbi_result_get_string_idx (result, 1)};
305 retval.push_back(index_name);
307 dbi_result_free (result);
316 auto tables = get_table_list(conn,
"");
317 for (
auto table_name : tables)
319 auto result = dbi_conn_queryf (conn,
320 "SHOW INDEXES IN %s WHERE Key_name != 'PRIMARY'",
322 if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE)
324 PWARN (
"Index Table Retrieval Error: %s on table %s\n",
325 errmsg, table_name.c_str());
329 while (dbi_result_next_row (result) != 0)
331 std::string index_name {dbi_result_get_string_idx (result, 3)};
332 retval.push_back(index_name +
" " + table_name);
334 dbi_result_free (result);
345 PINFO (
"Retrieving postgres index list\n");
346 auto result = dbi_conn_query (conn,
347 "SELECT relname FROM pg_class AS a INNER JOIN pg_index AS b ON (b.indexrelid = a.oid) INNER JOIN pg_namespace AS c ON (a.relnamespace = c.oid) WHERE reltype = '0' AND indisprimary = 'f' AND nspname = 'public'");
348 if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE)
350 PWARN(
"Index Table Retrieval Error: %s\n", errmsg);
353 while (dbi_result_next_row (result) != 0)
355 std::string index_name {dbi_result_get_string_idx (result, 1)};
356 retval.push_back(index_name);
358 dbi_result_free (result);
362 template <DbType P>
void 365 dbi_result result = dbi_conn_queryf (conn,
"DROP INDEX %s", index.c_str());
367 dbi_result_free (result);
374 auto sep = index.find(
' ', 0);
375 if (index.find(
' ', sep + 1) != std::string::npos)
377 PWARN(
"Drop index error: invalid MySQL index format (<index> <table>): %s",
382 auto result = dbi_conn_queryf (conn,
"DROP INDEX %s ON %s",
383 index.substr(0, sep).c_str(),
384 index.substr(sep + 1).c_str());
386 dbi_result_free (result);
388 #endif //__GNC_DBISQLPROVIDERIMPL_HPP__ information required to create a column in a table.
load and save data to SQL via libdbi
#define PINFO(format, args...)
Print an informational note.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.