LeechCraft  0.6.70-16373-g319c272718
Modular cross-platform feature rich live environment.
migrate.h
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7  **********************************************************************/
8 
9 #pragma once
10 
11 #include "util/db/oral/oral.h"
12 #include <util/sll/qtutil.h>
13 
14 namespace LC::Util::oral
15 {
16  namespace detail
17  {
18  bool MatchesSchema (const QString& baseName, const QString& schema, QSqlDatabase& db)
19  {
20  auto result = Util::RunTextQuery (db,
21  "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '%1'"_qs
22  .arg (baseName));
23  if (!result.next ())
24  return true;
25 
26  const auto& existingDDL = result.value (0).toString ();
27 
28  auto figureOutFields = [] (const QString& str)
29  {
30  auto firstOpen = str.indexOf ('(');
31  auto lastClose = str.lastIndexOf (')');
32  return str.midRef (firstOpen, lastClose - firstOpen);
33  };
34  auto existing = figureOutFields (existingDDL);
35  auto suggested = figureOutFields (schema);
36  return existing == suggested;
37  }
38  }
39 
40  template<typename Record, typename ImplFactory = SQLiteImplFactory>
41  void Migrate (QSqlDatabase& db)
42  {
43  constexpr auto baseName = Record::ClassName;
44  constexpr auto thisName = "copy" + baseName;
45  const auto& schema = ToString<detail::AdaptCreateTableNamed<thisName, ImplFactory, Record> ()> ();
46 
47  const auto& baseNameStr = ToString<baseName> ();
48  const auto& thisNameStr = ToString<thisName> ();
49  if (detail::MatchesSchema (baseNameStr, schema, db))
50  {
51  qDebug () << Q_FUNC_INFO
52  << "not migrating"
53  << db.connectionName ();
54  return;
55  }
56 
57  qDebug () << Q_FUNC_INFO
58  << "migrating"
59  << db.connectionName ();
60 
61  Util::DBLock lock { db };
62  lock.Init ();
63 
64  Util::RunTextQuery (db, schema);
65 
66  constexpr auto fields = JoinTup (detail::FieldNames<Record>, ", ");
67 
69  "INSERT INTO %2 (%1) SELECT %1 FROM %3;"_qs
70  .arg (ToString<fields> (), thisNameStr, baseNameStr));
71 
73  "DROP TABLE %1;"_qs
74  .arg (baseNameStr));
76  "ALTER TABLE %1 RENAME TO %2;"_qs
77  .arg (thisNameStr, baseNameStr));
78 
79  lock.Good ();
80  }
81 }
UTIL_DB_API void Init()
Initializes the transaction.
Definition: dblock.cpp:45
constexpr auto JoinTup(auto &&stringsTuple, auto &&sep) noexcept
Definition: ctstringutils.h:29
Provides database transaction lock.
Definition: dblock.h:41
void Migrate(QSqlDatabase &db)
Definition: migrate.h:41
constexpr detail::MemberPtrs< Ptrs... > fields
Definition: oral.h:954
QSqlQuery RunTextQuery(const QSqlDatabase &db, const QString &text)
Runs the given query text on the given db.
Definition: util.cpp:18
bool MatchesSchema(const QString &baseName, const QString &schema, QSqlDatabase &db)
Definition: migrate.h:18