Zserio C++ runtime library  1.2.0
Built for Zserio 2.16.0
ValidationSqliteUtil.h
Go to the documentation of this file.
1 #ifndef ZSERIO_VALIDATION_SQLITE_UTIL_H_INC
2 #define ZSERIO_VALIDATION_SQLITE_UTIL_H_INC
3 
4 #include <map>
5 
6 #include "zserio/RebindAlloc.h"
9 #include "zserio/String.h"
10 #include "zserio/StringView.h"
11 
12 namespace zserio
13 {
14 
16 template <typename ALLOC>
18 {
20  using Statement = std::unique_ptr<sqlite3_stmt, SqliteFinalizer>;
21 
26  {
29  bool isNotNull;
30  bool isPrimaryKey;
31  };
32 
33  using TableSchema = std::map<string_type, ColumnDescription, std::less<string_type>,
35 
48  static size_t getNumberOfTableRows(SqliteConnection& connection, StringView attachedDbName,
49  StringView tableName, const ALLOC& allocator)
50  {
51  string_type sqlQuery(allocator);
52  sqlQuery += "SELECT count(*) FROM ";
53  if (!attachedDbName.empty())
54  {
55  sqlQuery += attachedDbName;
56  sqlQuery += ".";
57  }
58  sqlQuery += tableName;
59 
60  Statement statement(connection.prepareStatement(sqlQuery));
61  const int result = sqlite3_step(statement.get());
62  if (result != SQLITE_ROW)
63  {
64  throw SqliteException("ValidationSqliteUtils.getNumberOfTableRows: sqlite3_step() failed: ")
65  << SqliteErrorCode(result);
66  }
67 
68  return static_cast<size_t>(sqlite3_column_int64(statement.get(), 0));
69  }
70 
80  static void getTableSchema(SqliteConnection& connection, StringView attachedDbName, StringView tableName,
81  TableSchema& tableSchema, const ALLOC& allocator)
82  {
83  string_type sqlQuery(allocator);
84  sqlQuery += "PRAGMA ";
85  if (!attachedDbName.empty())
86  {
87  sqlQuery += attachedDbName;
88  sqlQuery += ".";
89  }
90  sqlQuery += "table_info(";
91  sqlQuery += tableName;
92  sqlQuery += ")";
93 
94  Statement statement(connection.prepareStatement(sqlQuery));
95 
96  int result = SQLITE_OK;
97  while ((result = sqlite3_step(statement.get())) == SQLITE_ROW)
98  {
99  const char* columnName = reinterpret_cast<const char*>(sqlite3_column_text(statement.get(), 1));
100  const char* columnType = reinterpret_cast<const char*>(sqlite3_column_text(statement.get(), 2));
101  tableSchema.emplace(string_type(columnName, allocator),
103  string_type(columnName, allocator), string_type(columnType, allocator),
104  sqlite3_column_int(statement.get(), 3) != 0, // is not null
105  sqlite3_column_int(statement.get(), 5) != 0 // is primary key
106  });
107  }
108 
109  if (result != SQLITE_DONE)
110  {
111  throw SqliteException("ValidationSqliteUtils.getTableSchema: sqlite3_step() failed: ")
112  << SqliteErrorCode(result);
113  }
114  }
115 
129  static bool isColumnInTable(SqliteConnection& connection, StringView attachedDbName, StringView tableName,
130  StringView columnName, const ALLOC& allocator)
131  {
132  // try select to check if hidden column exists
133  string_type sqlQuery(allocator);
134  sqlQuery += "SELECT ";
135  sqlQuery += columnName;
136  sqlQuery += " FROM ";
137  if (!attachedDbName.empty())
138  {
139  sqlQuery += attachedDbName;
140  sqlQuery += ".";
141  }
142  sqlQuery += tableName;
143  sqlQuery += " LIMIT 0";
144 
145  try
146  {
147  Statement statement(connection.prepareStatement(sqlQuery));
148  return sqlite3_step(statement.get()) == SQLITE_DONE;
149  }
150  catch (const SqliteException&)
151  {
152  return false;
153  }
154  }
155 
163  static const char* sqliteColumnTypeName(int columnType)
164  {
165  switch (columnType)
166  {
167  case SQLITE_INTEGER:
168  return "INTEGER";
169  case SQLITE_FLOAT:
170  return "REAL";
171  case SQLITE_TEXT:
172  return "TEXT";
173  case SQLITE_BLOB:
174  return "BLOB";
175  default:
176  return "NULL";
177  }
178  }
179 };
180 
181 } // namespace zserio
182 
183 #endif // ZSERIO_VALIDATION_SQLITE_UTIL_H_INC
constexpr bool empty() const noexcept
Definition: StringView.h:270
sqlite3_stmt * prepareStatement(StringView sqlQuery)
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
Definition: RebindAlloc.h:10
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char > > string
Definition: String.h:17
static size_t getNumberOfTableRows(SqliteConnection &connection, StringView attachedDbName, StringView tableName, const ALLOC &allocator)
static void getTableSchema(SqliteConnection &connection, StringView attachedDbName, StringView tableName, TableSchema &tableSchema, const ALLOC &allocator)
static const char * sqliteColumnTypeName(int columnType)
std::map< string_type, ColumnDescription, std::less< string_type >, RebindAlloc< ALLOC, std::pair< const string_type, ColumnDescription > >> TableSchema
static bool isColumnInTable(SqliteConnection &connection, StringView attachedDbName, StringView tableName, StringView columnName, const ALLOC &allocator)
std::unique_ptr< sqlite3_stmt, SqliteFinalizer > Statement