File: state.cpp

package info (click to toggle)
bibledit-cloud 5.1.036-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 250,636 kB
  • sloc: xml: 915,934; ansic: 261,349; cpp: 92,628; javascript: 32,542; sh: 4,915; makefile: 586; php: 69
file content (188 lines) | stat: -rw-r--r-- 5,512 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
Copyright (©) 2003-2025 Teus Benschop.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include <database/state.h>
#include <filter/url.h>
#include <filter/string.h>
#include <filter/memory.h>
#include <database/sqlite.h>


// Database resilience: It only contains state information.
// It is checked and optionally recreated every night.


constexpr const auto state {"state"};


void Database_State::create ()
{
  bool healthy_database = database::sqlite::healthy (state);
  if (!healthy_database) {
    filter_url_unlink (database::sqlite::get_file (state));
  }

  SqliteDatabase sql (state);
  
  // On Android, this pragma prevents the following error: VACUUM; Unable to open database file.
  sql.set_sql ("PRAGMA temp_store = MEMORY;");
  sql.execute ();
  
  sql.set_sql ("CREATE TABLE IF NOT EXISTS notes ("
               " first integer,"
               " last integer,"
               " value text"
               ");");
  sql.execute ();
  
  sql.set_sql ("DELETE FROM notes;");
  sql.execute ();
  
  // Here something weird was going on when doing a VACUUM at this stage.
  // On Android, it always would say this: VACUUM; Unable to open database file.
  // Testing on the existence of the database file, right before the VACUUM operation, showed that the database file did exist. The question is then: If the file exists, why does it fail to open it?
  // It also was tried to delay with 100 milliseconds before doing the VACUUM. But this made no difference. It would still give the error.
  // It also was tried to close the connection to the database, then open it again. This made no difference either.
  // It now does not VACUUM a newly created database, but only when it was created.
  // Later on, the PRAGMA as above was used to solve the issue.
  sql.set_sql ("VACUUM;");
  sql.execute ();

  sql.set_sql ("CREATE TABLE IF NOT EXISTS export ("
               " bible text,"
               " book integer,"
               " format integer"
               ");");
  sql.execute ();
  
  sql.set_sql ("CREATE TABLE IF NOT EXISTS exported ("
               " bible text,"
               " book integer,"
               " state boolean"
               ");");
  sql.execute ();
}


// Stores a notes checksum for a range of notes.
void Database_State::putNotesChecksum (int first, int last, const std::string& checksum)
{
  SqliteDatabase sql (state);

  // Remove possible existing range.
  sql.add ("DELETE FROM notes WHERE first =");
  sql.add (first);
  sql.add ("AND last =");
  sql.add (last);
  sql.add (";");
  sql.execute ();
  
  // Store the new checksum for the range.
  sql.clear();
  sql.add ("INSERT INTO notes VALUES (");
  sql.add (first);
  sql.add (",");
  sql.add (last);
  sql.add (",");
  sql.add (checksum);
  sql.add (");");
  sql.execute ();
}


// Retrieves the checksum for a range of notes.
std::string Database_State::getNotesChecksum (int first, int last)
{
  // Receive the checksum for the exact range.
  SqliteDatabase sql (state);
  sql.add ("SELECT value FROM notes WHERE first =");
  sql.add (first);
  sql.add ("AND last =");
  sql.add (last);
  sql.add (";");
  const std::vector <std::string> values = sql.query ()["value"];
  if (!values.empty()) {
    return values.at(0);
  }
  return std::string();
}


// Erase the checksum for a note contained in any range.
void Database_State::eraseNoteChecksum (int identifier)
{
  // Remove ranges that contain the note identifier.
  SqliteDatabase sql (state);
  sql.add ("DELETE FROM notes WHERE first <=");
  sql.add (identifier);
  sql.add ("AND last >=");
  sql.add (identifier);
  sql.add (";");
  sql.execute ();
}


// Flag export of $bible $book to $format.
void Database_State::setExport (const std::string& bible, int book, int format)
{
  if (getExport (bible, book, format)) return;
  SqliteDatabase sql (state);
  sql.add ("INSERT INTO export VALUES (");
  sql.add (bible);
  sql.add (",");
  sql.add (book);
  sql.add (",");
  sql.add (format);
  sql.add (");");
  sql.execute ();
}


// Get whether the $bible $book has been flagged for export in format $format.
bool Database_State::getExport (const std::string& bible, int book, int format)
{
  SqliteDatabase sql (state);
  sql.add ("SELECT format FROM export WHERE bible =");
  sql.add (bible);
  sql.add ("AND book =");
  sql.add (book);
  sql.add ("AND format =");
  sql.add (format);
  sql.add (";");
  const std::vector <std::string> values = sql.query ()["format"];
  if (!values.empty()) {
    return true;
  }
  return false;
}


// Clear the export flag for $bible $book to $format
void Database_State::clearExport (const std::string& bible, int book, int format)
{
  SqliteDatabase sql (state);
  sql.add ("DELETE FROM export WHERE bible =");
  sql.add (bible);
  sql.add ("AND book =");
  sql.add (book);
  sql.add ("AND format =");
  sql.add (format);
  sql.add (";");
  sql.execute ();
}