Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.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"
7 #include "zserio/String.h"
8 #include "zserio/StringView.h"
10 #include "zserio/SqliteFinalizer.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<
36 
49  static size_t getNumberOfTableRows(SqliteConnection& connection, StringView attachedDbName,
50  StringView tableName, const ALLOC& allocator)
51  {
52  string_type sqlQuery(allocator);
53  sqlQuery += "SELECT count(*) FROM ";
54  if (!attachedDbName.empty())
55  {
56  sqlQuery += attachedDbName;
57  sqlQuery += ".";
58  }
59  sqlQuery += tableName;
60 
61  Statement statement(connection.prepareStatement(sqlQuery));
62  const int result = sqlite3_step(statement.get());
63  if (result != SQLITE_ROW)
64  {
65  throw SqliteException("ValidationSqliteUtils.getNumberOfTableRows: sqlite3_step() failed: ") <<
66  SqliteErrorCode(result);
67  }
68 
69  return static_cast<size_t>(sqlite3_column_int64(statement.get(), 0));
70  }
71 
81  static void getTableSchema(SqliteConnection& connection, StringView attachedDbName,
82  StringView tableName, TableSchema& tableSchema, const ALLOC& allocator)
83  {
84  string_type sqlQuery(allocator);
85  sqlQuery += "PRAGMA ";
86  if (!attachedDbName.empty())
87  {
88  sqlQuery += attachedDbName;
89  sqlQuery += ".";
90  }
91  sqlQuery += "table_info(";
92  sqlQuery += tableName;
93  sqlQuery += ")";
94 
95  Statement statement(connection.prepareStatement(sqlQuery));
96 
97  int result = SQLITE_OK;
98  while ((result = sqlite3_step(statement.get())) == SQLITE_ROW)
99  {
100  const char* columnName = reinterpret_cast<const char*>(sqlite3_column_text(statement.get(), 1));
101  const char* columnType = reinterpret_cast<const char*>(sqlite3_column_text(statement.get(), 2));
102  tableSchema.emplace(string_type(columnName, allocator),
103  ColumnDescription
104  {
105  string_type(columnName, allocator),
106  string_type(columnType, allocator),
107  sqlite3_column_int(statement.get(), 3) != 0, // is not null
108  sqlite3_column_int(statement.get(), 5) != 0 // is primary key
109  });
110  }
111 
112  if (result != SQLITE_DONE)
113  {
114  throw SqliteException("ValidationSqliteUtils.getTableSchema: sqlite3_step() failed: ") <<
115  SqliteErrorCode(result);
116  }
117  }
118 
132  static bool isColumnInTable(SqliteConnection& connection, StringView attachedDbName,
133  StringView tableName, StringView columnName, const ALLOC& allocator)
134  {
135  // try select to check if hidden column exists
136  string_type sqlQuery(allocator);
137  sqlQuery += "SELECT ";
138  sqlQuery += columnName;
139  sqlQuery += " FROM ";
140  if (!attachedDbName.empty())
141  {
142  sqlQuery += attachedDbName;
143  sqlQuery += ".";
144  }
145  sqlQuery += tableName;
146  sqlQuery += " LIMIT 0";
147 
148  try
149  {
150  Statement statement(connection.prepareStatement(sqlQuery));
151  return sqlite3_step(statement.get()) == SQLITE_DONE;
152  }
153  catch (const SqliteException&)
154  {
155  return false;
156  }
157  }
158 
166  static const char* sqliteColumnTypeName(int columnType)
167  {
168  switch (columnType)
169  {
170  case SQLITE_INTEGER:
171  return "INTEGER";
172  case SQLITE_FLOAT:
173  return "REAL";
174  case SQLITE_TEXT:
175  return "TEXT";
176  case SQLITE_BLOB:
177  return "BLOB";
178  default:
179  return "NULL";
180  }
181  }
182 };
183 
184 } // namespace zserio
185 
186 #endif // ZSERIO_VALIDATION_SQLITE_UTIL_H_INC
std::map< string_type, ColumnDescription, std::less< string_type >, RebindAlloc< ALLOC, std::pair< const string_type, ColumnDescription >>> TableSchema
sqlite3_stmt * prepareStatement(StringView sqlQuery)
static const char * sqliteColumnTypeName(int columnType)
static size_t getNumberOfTableRows(SqliteConnection &connection, StringView attachedDbName, StringView tableName, const ALLOC &allocator)
std::map< KEY, T, COMPARE, PropagatingPolymorphicAllocator< std::pair< const KEY, T >>> map
Definition: Map.h:17
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char >> string
Definition: String.h:16
constexpr bool empty() const noexcept
Definition: StringView.h:267
static void getTableSchema(SqliteConnection &connection, StringView attachedDbName, StringView tableName, TableSchema &tableSchema, const ALLOC &allocator)
static bool isColumnInTable(SqliteConnection &connection, StringView attachedDbName, StringView tableName, StringView columnName, const ALLOC &allocator)
std::unique_ptr< sqlite3_stmt, SqliteFinalizer > Statement
typename std::allocator_traits< ALLOC >::template rebind_alloc< T > RebindAlloc
Definition: RebindAlloc.h:10