1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * \author guonix
17 * \date Oct 2020
18 * \brief
19 */
20
21#include "sqlite_meta_store.h"
22#include <ailego/hash/fnv1.h>
23#include <ailego/internal/platform.h>
24#include "common/error_code.h"
25#include "common/logger.h"
26#include "meta/meta_store_factory.h"
27
28namespace proxima {
29namespace be {
30namespace meta {
31namespace sqlite {
32
33#define SQLITE_SQL_CODE(__VALUE__) SQLITE_SQL_HASH_##__VALUE__
34#define SQLITE_SQL_STR(__VALUE__) SQLITE_SQL##__VALUE__
35
36#define DEFINE_SQLITE_SQL(__VALUE__, __SQL__) \
37 constexpr const char *SQLITE_SQL##__VALUE__ = __SQL__; \
38 constexpr uint32_t SQLITE_SQL_HASH_##__VALUE__ = ailego::Fnv1::Hash32(__SQL__)
39
40// Global Sql Statements
41// Create Collection SQL
42DEFINE_SQLITE_SQL(kCreateCollection,
43 "INSERT INTO "
44 "collections(name, uid, uuid, forward_columns, "
45 "max_docs_per_segment, revision, status, "
46 "current, io_mode) "
47 "VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9);");
48
49// Update Collection SQL
50DEFINE_SQLITE_SQL(
51 kUpdateCollection,
52 "UPDATE collections set name=?1, uid=?2, "
53 "forward_columns=?3, max_docs_per_segment=?4, revision=?5, status=?6, "
54 "current=?7, io_mode=?8 WHERE uuid=?9;");
55
56// Delete Collection SQL
57DEFINE_SQLITE_SQL(kDeleteCollection, "DELETE FROM collections WHERE name=?1;");
58
59// Delete Collection by uuid SQL
60DEFINE_SQLITE_SQL(kDeleteCollectionByUUID,
61 "DELETE FROM collections WHERE uuid=?1;");
62
63// List All Collection SQL
64DEFINE_SQLITE_SQL(kListAllCollections, "SELECT * from collections;");
65
66// Create Column SQL
67DEFINE_SQLITE_SQL(kCreateColumn,
68 "INSERT INTO "
69 "columns(collection_uid, collection_uuid, name, uid, "
70 "dimension, index_type, "
71 "data_type, parameters) "
72 "VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);");
73
74// Delete Column SQL
75DEFINE_SQLITE_SQL(kDeleteColumn,
76 "DELETE FROM columns WHERE collection_uid=?1;");
77
78// Delete Column by uuid SQL
79DEFINE_SQLITE_SQL(kDeleteColumnByUUID,
80 "DELETE FROM columns WHERE collection_uuid=?1;");
81
82// List Column SQL
83DEFINE_SQLITE_SQL(kListColumn, "SELECT * from columns;");
84
85// Create Repository SQL
86DEFINE_SQLITE_SQL(kCreateRepository,
87 "INSERT INTO "
88 "database_repositories (name, collection_uid, "
89 "collection_uuid, table_name, connection, user, password) "
90 "VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7);");
91
92// Delete Repositories SQL
93DEFINE_SQLITE_SQL(kDeleteRepositoriesByUID,
94 "DELETE FROM database_repositories WHERE collection_uid=?1;");
95
96// Delete Repositories SQL
97DEFINE_SQLITE_SQL(
98 kDeleteRepositoriesByUUID,
99 "DELETE FROM database_repositories WHERE collection_uuid=?1;");
100
101// List All Repositories SQL
102DEFINE_SQLITE_SQL(kListAllRepositories, "SELECT * from database_repositories;");
103
104
105//! Constructor
106SQLiteMetaStore::SQLiteMetaStore() = default;
107
108//! Destructor
109SQLiteMetaStore::~SQLiteMetaStore() {
110 do_cleanup();
111}
112
113//! initialize metastore
114int SQLiteMetaStore::initialize(const ailego::Uri *uri) {
115 ailego_assert_with(uri != nullptr, "Invalid uri param passed");
116 if (initialized_) {
117 return 0;
118 }
119
120 if (!uri || !uri->is_valid()) {
121 return PROXIMA_BE_ERROR_CODE(RuntimeError);
122 }
123
124 // check sqlite3 macro MULTITHREAD or SERIALIZED
125 if (sqlite3_threadsafe() == 0) {
126 LOG_ERROR(
127 "Sqlite should be compiled with macro SQLITE_THREADSAFE = 1 or 2");
128 return PROXIMA_BE_ERROR_CODE(RuntimeError);
129 }
130
131 sqlite3 *handle = nullptr;
132 database_ = uri->path();
133 int code =
134 sqlite3_open_v2(database_.c_str(), &handle,
135 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
136 if (code != SQLITE_OK) {
137 LOG_ERROR("Failed to open sqlite db. msg[%s]", sqlite3_errstr(code));
138 return PROXIMA_BE_ERROR_CODE(RuntimeError);
139 }
140
141 //! Synchronize Schema
142 code = sync(handle);
143 if (code == 0) {
144 // init statements
145 code = init_statements(database_);
146 }
147
148 if (code == 0) {
149 initialized_ = true;
150 }
151
152 sqlite3_close(handle);
153 return code;
154}
155
156int SQLiteMetaStore::cleanup() {
157 return do_cleanup();
158}
159
160#define SQLITE_METASTORE_INITIALIZE_CHECK() \
161 if (!initialized_) return PROXIMA_BE_ERROR_CODE(RuntimeError)
162
163//! Create the collection
164int SQLiteMetaStore::create_collection(const CollectionObject &collection) {
165 SQLITE_METASTORE_INITIALIZE_CHECK();
166
167 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kCreateCollection));
168
169 int code = stmt->exec(
170 [&collection](sqlite3_stmt *s) -> int {
171 sqlite3_bind_text(s, 1, collection.name().c_str(),
172 collection.name().length(), nullptr);
173 sqlite3_bind_text(s, 2, collection.uid().c_str(),
174 collection.uid().length(), nullptr);
175 sqlite3_bind_text(s, 3, collection.uuid().c_str(),
176 collection.uuid().length(), nullptr);
177 sqlite3_bind_text(s, 4, collection.forward_columns().c_str(),
178 collection.forward_columns().length(), nullptr);
179 sqlite3_bind_int64(
180 s, 5,
181 static_cast<sqlite3_int64>(collection.max_docs_per_segment()));
182 sqlite3_bind_int(s, 6, collection.revision());
183 sqlite3_bind_int(s, 7, collection.status());
184 sqlite3_bind_int(s, 8, collection.current());
185 sqlite3_bind_int(s, 9, collection.io_mode());
186 return 0;
187 },
188 nullptr);
189
190 if (code != 0) {
191 LOG_ERROR("Failed to create collection. code[%d]", code);
192 }
193 return code;
194}
195
196//! Update collection declaration
197int SQLiteMetaStore::update_collection(const CollectionObject &collection) {
198 SQLITE_METASTORE_INITIALIZE_CHECK();
199
200 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kUpdateCollection));
201 int code = stmt->exec(
202 [&collection](sqlite3_stmt *s) -> int {
203 sqlite3_bind_text(s, 1, collection.name().c_str(),
204 collection.name().length(), nullptr);
205 sqlite3_bind_text(s, 2, collection.uid().c_str(),
206 collection.uid().length(), nullptr);
207 sqlite3_bind_text(s, 3, collection.forward_columns().c_str(),
208 collection.forward_columns().length(), nullptr);
209 sqlite3_bind_int64(
210 s, 4,
211 static_cast<sqlite3_int64>(collection.max_docs_per_segment()));
212 sqlite3_bind_int(s, 5, collection.revision());
213 sqlite3_bind_int(s, 6, collection.status());
214 sqlite3_bind_int(s, 7, collection.current());
215 sqlite3_bind_int(s, 8, collection.io_mode());
216 sqlite3_bind_text(s, 9, collection.uuid().c_str(),
217 collection.uuid().length(), nullptr);
218 return 0;
219 },
220 nullptr);
221 if (code != 0) {
222 LOG_ERROR("Failed to update collection. code[%d]", code);
223 }
224
225 return code;
226}
227
228//! Delete collection
229int SQLiteMetaStore::delete_collection(const std::string &name) {
230 SQLITE_METASTORE_INITIALIZE_CHECK();
231
232 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kDeleteCollection));
233
234 int code = stmt->exec(
235 [&name](sqlite3_stmt *s) -> int {
236 sqlite3_bind_text(s, 1, name.c_str(), name.length(), nullptr);
237 return 0;
238 },
239 nullptr);
240 if (code != 0) {
241 LOG_ERROR("Failed to delete collection. code[%d]", code);
242 }
243
244 return code;
245}
246
247int SQLiteMetaStore::delete_collection_by_uuid(const std::string &uuid) {
248 SQLITE_METASTORE_INITIALIZE_CHECK();
249
250 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kDeleteCollectionByUUID));
251
252 int code = stmt->exec(
253 [&uuid](sqlite3_stmt *s) -> int {
254 sqlite3_bind_text(s, 1, uuid.c_str(), uuid.length(), nullptr);
255 return 0;
256 },
257 nullptr);
258 if (code != 0) {
259 LOG_ERROR("Failed to delete collection. code[%d]", code);
260 }
261
262 return code;
263}
264
265namespace {
266static std::function<int(sqlite3_stmt *)> BuildFetcher(
267 CollectionObject *collection_ptr) {
268 return [=](sqlite3_stmt *s) -> int {
269 collection_ptr->set_id(sqlite3_column_int64(s, 0));
270 collection_ptr->mutable_name()->assign(
271 reinterpret_cast<const char *>(sqlite3_column_text(s, 1)));
272 collection_ptr->mutable_uid()->assign(
273 reinterpret_cast<const char *>(sqlite3_column_text(s, 2)));
274 collection_ptr->mutable_uuid()->assign(
275 reinterpret_cast<const char *>(sqlite3_column_text(s, 3)));
276 collection_ptr->mutable_forward_columns()->assign(
277 reinterpret_cast<const char *>(sqlite3_column_text(s, 4)));
278 collection_ptr->set_max_docs_per_segment(sqlite3_column_int64(s, 5));
279 collection_ptr->set_revision(sqlite3_column_int(s, 6));
280 collection_ptr->set_status(sqlite3_column_int(s, 7));
281 collection_ptr->set_current(sqlite3_column_int(s, 8));
282 collection_ptr->set_io_mode(sqlite3_column_int(s, 9));
283 return 0;
284 };
285}
286
287static std::function<int(sqlite3_stmt *)> BuildFetcher(ColumnObject *column) {
288 return [=](sqlite3_stmt *s) -> int {
289 column->set_id(sqlite3_column_int64(s, 0));
290 column->mutable_collection_uid()->assign(
291 reinterpret_cast<const char *>(sqlite3_column_text(s, 1)));
292 column->mutable_collection_uuid()->assign(
293 reinterpret_cast<const char *>(sqlite3_column_text(s, 2)));
294 column->mutable_name()->assign(
295 reinterpret_cast<const char *>(sqlite3_column_text(s, 3)));
296 column->mutable_uid()->assign(
297 reinterpret_cast<const char *>(sqlite3_column_text(s, 4)));
298 column->set_dimension(sqlite3_column_int(s, 5));
299 column->set_index_type(sqlite3_column_int(s, 6));
300 column->set_data_type(sqlite3_column_int(s, 7));
301 column->mutable_parameters()->assign(
302 reinterpret_cast<const char *>(sqlite3_column_text(s, 8)));
303 return 0;
304 };
305}
306
307static std::function<int(sqlite3_stmt *)> BuildFetcher(
308 DatabaseRepositoryObject *repository) {
309 return [=](sqlite3_stmt *s) -> int {
310 repository->set_id(sqlite3_column_int64(s, 0));
311 repository->mutable_name()->assign(
312 reinterpret_cast<const char *>(sqlite3_column_text(s, 1)));
313 repository->mutable_collection_uid()->assign(
314 reinterpret_cast<const char *>(sqlite3_column_text(s, 2)));
315 repository->mutable_collection_uuid()->assign(
316 reinterpret_cast<const char *>(sqlite3_column_text(s, 3)));
317 repository->mutable_table()->assign(
318 reinterpret_cast<const char *>(sqlite3_column_text(s, 4)));
319 repository->mutable_connection()->assign(
320 reinterpret_cast<const char *>(sqlite3_column_text(s, 5)));
321 repository->mutable_user()->assign(
322 reinterpret_cast<const char *>(sqlite3_column_text(s, 6)));
323 repository->mutable_password()->assign(
324 reinterpret_cast<const char *>(sqlite3_column_text(s, 7)));
325 return 0;
326 };
327}
328
329} // namespace
330
331//! Retrieve all collections
332int SQLiteMetaStore::list_collections(CollectionAllocator allocator) const {
333 SQLITE_METASTORE_INITIALIZE_CHECK();
334
335 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kListAllCollections));
336
337 int code = stmt->exec(nullptr, [&allocator](sqlite3_stmt *s) -> int {
338 int fetch_code = BuildFetcher(allocator())(s);
339 if (fetch_code != 0) {
340 LOG_ERROR("Failed to fetch collection from sqlite statement");
341 }
342 return fetch_code;
343 });
344
345 return code;
346}
347
348//! Create column
349int SQLiteMetaStore::create_column(const ColumnObject &column) {
350 SQLITE_METASTORE_INITIALIZE_CHECK();
351
352 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kCreateColumn));
353
354 int code = stmt->exec(
355 [&column](sqlite3_stmt *s) -> int {
356 sqlite3_bind_text(s, 1, column.collection_uid().c_str(),
357 column.collection_uid().length(), nullptr);
358 sqlite3_bind_text(s, 2, column.collection_uuid().c_str(),
359 column.collection_uuid().length(), nullptr);
360 sqlite3_bind_text(s, 3, column.name().c_str(), column.name().length(),
361 nullptr);
362 sqlite3_bind_text(s, 4, column.uid().c_str(), column.uid().length(),
363 nullptr);
364 sqlite3_bind_int(s, 5, column.dimension());
365 sqlite3_bind_int(s, 6, column.index_type());
366 sqlite3_bind_int(s, 7, column.data_type());
367 sqlite3_bind_text(s, 8, column.parameters().c_str(),
368 column.parameters().length(), nullptr);
369 return 0;
370 },
371 nullptr);
372
373 if (code != 0) {
374 LOG_ERROR("Failed to create column. code[%d]", code);
375 }
376 return code;
377}
378
379//! Delete column
380int SQLiteMetaStore::delete_columns_by_uid(const std::string &uid) {
381 SQLITE_METASTORE_INITIALIZE_CHECK();
382
383 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kDeleteColumn));
384
385 int code = stmt->exec(
386 [&uid](sqlite3_stmt *s) -> int {
387 sqlite3_bind_text(s, 1, uid.c_str(), uid.length(), nullptr);
388 return 0;
389 },
390 nullptr);
391 if (code != 0) {
392 LOG_ERROR("Failed to delete column. code[%d]", code);
393 }
394
395 return code;
396}
397
398//! Delete column
399int SQLiteMetaStore::delete_columns_by_uuid(const std::string &uuid) {
400 SQLITE_METASTORE_INITIALIZE_CHECK();
401
402 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kDeleteColumnByUUID));
403
404 int code = stmt->exec(
405 [&uuid](sqlite3_stmt *s) -> int {
406 sqlite3_bind_text(s, 1, uuid.c_str(), uuid.length(), nullptr);
407 return 0;
408 },
409 nullptr);
410 if (code != 0) {
411 LOG_ERROR("Failed to delete column. code[%d]", code);
412 }
413
414 return code;
415}
416
417//! Retrieve columns
418int SQLiteMetaStore::list_columns(ColumnAllocator allocator) const {
419 SQLITE_METASTORE_INITIALIZE_CHECK();
420
421 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kListColumn));
422
423 int code = stmt->exec(nullptr, [&allocator](sqlite3_stmt *s) -> int {
424 int fetch_code = BuildFetcher(allocator())(s);
425 if (fetch_code != 0) {
426 LOG_ERROR("Failed to fetch column from sqlite statement");
427 }
428 return fetch_code;
429 });
430
431 return code;
432}
433
434//! Create repository
435int SQLiteMetaStore::create_repository(
436 const DatabaseRepositoryObject &repository) {
437 SQLITE_METASTORE_INITIALIZE_CHECK();
438
439 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kCreateRepository));
440
441 int code = stmt->exec(
442 [&repository](sqlite3_stmt *s) -> int {
443 sqlite3_bind_text(s, 1, repository.name().c_str(),
444 repository.name().length(), nullptr);
445 sqlite3_bind_text(s, 2, repository.collection_uid().c_str(),
446 repository.collection_uid().length(), nullptr);
447 sqlite3_bind_text(s, 3, repository.collection_uuid().c_str(),
448 repository.collection_uuid().length(), nullptr);
449 sqlite3_bind_text(s, 4, repository.table().c_str(),
450 repository.table().length(), nullptr);
451 sqlite3_bind_text(s, 5, repository.connection().c_str(),
452 repository.connection().length(), nullptr);
453 sqlite3_bind_text(s, 6, repository.user().c_str(),
454 repository.user().length(), nullptr);
455 sqlite3_bind_text(s, 7, repository.password().c_str(),
456 repository.password().length(), nullptr);
457 return 0;
458 },
459 nullptr);
460
461 if (code != 0) {
462 LOG_ERROR("Failed to create repository. code[%d]", code);
463 }
464 return code;
465}
466
467//! Delete repositories
468int SQLiteMetaStore::delete_repositories_by_uid(const std::string &uid) {
469 SQLITE_METASTORE_INITIALIZE_CHECK();
470
471 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kDeleteRepositoriesByUID));
472
473 int code = stmt->exec(
474 [&uid](sqlite3_stmt *s) -> int {
475 sqlite3_bind_text(s, 1, uid.c_str(), uid.length(), nullptr);
476 return 0;
477 },
478 nullptr);
479 if (code != 0) {
480 LOG_ERROR("Failed to delete repository. code[%d]", code);
481 }
482
483 return code;
484}
485
486//! Delete repositories
487int SQLiteMetaStore::delete_repositories_by_uuid(const std::string &uuid) {
488 SQLITE_METASTORE_INITIALIZE_CHECK();
489
490 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kDeleteRepositoriesByUUID));
491
492 int code = stmt->exec(
493 [&uuid](sqlite3_stmt *s) -> int {
494 sqlite3_bind_text(s, 1, uuid.c_str(), uuid.length(), nullptr);
495 return 0;
496 },
497 nullptr);
498 if (code != 0) {
499 LOG_ERROR("Failed to delete repository. code[%d]", code);
500 }
501
502 return code;
503}
504
505//! Retrieve all repositories
506int SQLiteMetaStore::list_repositories(
507 DatabaseRepositoryAllocator allocator) const {
508 SQLITE_METASTORE_INITIALIZE_CHECK();
509
510 StatementPtr &stmt = statement(SQLITE_SQL_CODE(kListAllRepositories));
511
512 int code = stmt->exec(nullptr, [&allocator](sqlite3_stmt *s) -> int {
513 int fetch_code = BuildFetcher(allocator())(s);
514 if (fetch_code != 0) {
515 LOG_ERROR("Failed to fetch repository from sqlite statement");
516 }
517 return fetch_code;
518 });
519
520 return code;
521}
522
523//! Flush all changes to storage
524int SQLiteMetaStore::flush() const {
525 return 0;
526}
527
528int SQLiteMetaStore::do_cleanup() {
529 for (auto &stmt : statements_) {
530 stmt.second->cleanup();
531 }
532
533 statements_.clear();
534 initialized_ = false;
535 return 0;
536}
537
538int SQLiteMetaStore::sync(sqlite3 *handle) {
539 static const char *kMetaTable =
540 "CREATE TABLE IF NOT EXISTS columns ( \n"
541 " id INTEGER PRIMARY KEY AUTOINCREMENT, \n"
542 " collection_uid TEXT NOT NULL, \n"
543 " collection_uuid TEXT NOT NULL, \n"
544 " name TEXT NOT NULL, \n"
545 " uid TEXT NOT NULL, \n"
546 " dimension INTEGER, \n"
547 " index_type INTEGER, \n"
548 " data_type INTEGER, \n"
549 " parameters TEXT DEFAULT '' \n"
550 ");"
551 "CREATE TABLE IF NOT EXISTS collections ("
552 " id INTEGER PRIMARY KEY AUTOINCREMENT, \n"
553 " name TEXT NOT NULL, \n"
554 " uid TEXT NOT NULL, \n"
555 " uuid TEXT NOT NULL UNIQUE, \n"
556 " forward_columns TEXT NOT NULL, \n"
557 " max_docs_per_segment INTEGER, \n"
558 " revision INTEGER, \n"
559 " status INTEGER, \n"
560 " current INTEGER, \n"
561 " io_mode INTEGER\n"
562 ");"
563 "CREATE TABLE IF NOT EXISTS database_repositories ("
564 " id INTEGER PRIMARY KEY AUTOINCREMENT, \n"
565 " name TEXT NOT NULL, \n"
566 " collection_uid TEXT NOT NULL, \n"
567 " collection_uuid TEXT NOT NULL, \n"
568 " table_name TEXT NOT NULL, \n"
569 " connection TEXT NOT NULL, \n"
570 " user TEXT NOT NULL, \n"
571 " password TEXT NOT NULL \n"
572 ");";
573
574 int code = sqlite3_exec(handle, kMetaTable, nullptr, nullptr, nullptr);
575 if (code != SQLITE_OK) {
576 LOG_ERROR("Failed to create table. msg[%s]", sqlite3_errstr(code));
577 return PROXIMA_BE_ERROR_CODE(RuntimeError);
578 }
579 return 0;
580}
581
582#define PREPARE_AND_CACHE_SQL(K, DB) \
583 { \
584 int code = put(SQLITE_SQL_CODE(K), \
585 std::make_shared<Statement>(DB, SQLITE_SQL_STR(K))); \
586 if (code != 0) { \
587 code = PROXIMA_BE_ERROR_CODE(RuntimeError); \
588 LOG_ERROR("Failed to prepare sql."); \
589 return code; \
590 } \
591 }
592
593int SQLiteMetaStore::init_statements(const std::string &database) {
594 PREPARE_AND_CACHE_SQL(kCreateCollection, database)
595 PREPARE_AND_CACHE_SQL(kUpdateCollection, database)
596 PREPARE_AND_CACHE_SQL(kDeleteCollection, database)
597 PREPARE_AND_CACHE_SQL(kDeleteCollectionByUUID, database)
598 PREPARE_AND_CACHE_SQL(kListAllCollections, database)
599
600 PREPARE_AND_CACHE_SQL(kCreateColumn, database)
601 PREPARE_AND_CACHE_SQL(kDeleteColumn, database)
602 PREPARE_AND_CACHE_SQL(kDeleteColumnByUUID, database)
603 PREPARE_AND_CACHE_SQL(kListColumn, database)
604
605 PREPARE_AND_CACHE_SQL(kCreateRepository, database)
606 PREPARE_AND_CACHE_SQL(kDeleteRepositoriesByUID, database)
607 PREPARE_AND_CACHE_SQL(kDeleteRepositoriesByUUID, database)
608 PREPARE_AND_CACHE_SQL(kListAllRepositories, database)
609 return 0;
610}
611
612#undef PREPARE_AND_CACHE_SQL
613
614StatementPtr &SQLiteMetaStore::statement(uint32_t index) const {
615 return statements_[index];
616}
617
618int SQLiteMetaStore::put(uint32_t hash, const StatementPtr &stmt) {
619 if (stmt->initialize() == 0) {
620 statements_[hash] = stmt;
621 return 0;
622 }
623 LOG_ERROR("Failed to initialize Statement");
624 return PROXIMA_BE_ERROR_CODE(RuntimeError);
625}
626
627#undef SQLITE_METASTORE_INITIALIZE_CHECK
628#undef DEFINE_SQLITE_SQL
629#undef SQLITE_SQL_STR
630#undef SQLITE_SQL_CODE
631
632META_FACTORY_REGISTER_INSTANCE_ALIAS(sqlite, SQLiteMetaStore);
633
634} // namespace sqlite
635} // namespace meta
636} // namespace be
637} // namespace proxima
638