Zserio C++ runtime library  1.0.2
Built for Zserio 2.14.1
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 unsigned char* columnNameText = sqlite3_column_text(statement.get(), 1);
100  const char* columnName = static_cast<const char*>(static_cast<const void*>(columnNameText));
101  const unsigned char* columnTypeText = sqlite3_column_text(statement.get(), 2);
102  const char* columnType = static_cast<const char*>(static_cast<const void*>(columnTypeText));
103  tableSchema.emplace(string_type(columnName, allocator),
105  string_type(columnName, allocator), string_type(columnType, allocator),
106  sqlite3_column_int(statement.get(), 3) != 0, // is not null
107  sqlite3_column_int(statement.get(), 5) != 0 // is primary key
108  });
109  }
110 
111  if (result != SQLITE_DONE)
112  {
113  throw SqliteException("ValidationSqliteUtils.getTableSchema: sqlite3_step() failed: ")
114  << SqliteErrorCode(result);
115  }
116  }
117 
131  static bool isColumnInTable(SqliteConnection& connection, StringView attachedDbName, StringView tableName,
132  StringView columnName, const ALLOC& allocator)
133  {
134  // try select to check if hidden column exists
135  string_type sqlQuery(allocator);
136  sqlQuery += "SELECT ";
137  sqlQuery += columnName;
138  sqlQuery += " FROM ";
139  if (!attachedDbName.empty())
140  {
141  sqlQuery += attachedDbName;
142  sqlQuery += ".";
143  }
144  sqlQuery += tableName;
145  sqlQuery += " LIMIT 0";
146 
147  try
148  {
149  Statement statement(connection.prepareStatement(sqlQuery));
150  return sqlite3_step(statement.get()) == SQLITE_DONE;
151  }
152  catch (const SqliteException&)
153  {
154  return false;
155  }
156  }
157 
165  static const char* sqliteColumnTypeName(int columnType)
166  {
167  switch (columnType)
168  {
169  case SQLITE_INTEGER:
170  return "INTEGER";
171  case SQLITE_FLOAT:
172  return "REAL";
173  case SQLITE_TEXT:
174  return "TEXT";
175  case SQLITE_BLOB:
176  return "BLOB";
177  default:
178  return "NULL";
179  }
180  }
181 };
182 
183 } // namespace zserio
184 
185 #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