MPD  0.20.18
Util.hxx
Go to the documentation of this file.
1 /*
2  * Copyright 2003-2017 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef MPD_SQLITE_UTIL_HXX
21 #define MPD_SQLITE_UTIL_HXX
22 
23 #include "Error.hxx"
24 
25 #include <sqlite3.h>
26 
27 #include <assert.h>
28 
32 static void
33 Bind(sqlite3_stmt *stmt, unsigned i, const char *value)
34 {
35  int result = sqlite3_bind_text(stmt, i, value, -1, nullptr);
36  if (result != SQLITE_OK)
37  throw SqliteError(stmt, result, "sqlite3_bind_text() failed");
38 }
39 
40 template<typename... Args>
41 static void
42 BindAll2(gcc_unused sqlite3_stmt *stmt, gcc_unused unsigned i)
43 {
44  assert(int(i - 1) == sqlite3_bind_parameter_count(stmt));
45 }
46 
47 template<typename... Args>
48 static void
49 BindAll2(sqlite3_stmt *stmt, unsigned i,
50  const char *value, Args&&... args)
51 {
52  Bind(stmt, i, value);
53  BindAll2(stmt, i + 1, std::forward<Args>(args)...);
54 }
55 
59 template<typename... Args>
60 static void
61 BindAll(sqlite3_stmt *stmt, Args&&... args)
62 {
63  assert(int(sizeof...(args)) == sqlite3_bind_parameter_count(stmt));
64 
65  BindAll2(stmt, 1, std::forward<Args>(args)...);
66 }
67 
72 static int
73 ExecuteBusy(sqlite3_stmt *stmt)
74 {
75  int result;
76  do {
77  result = sqlite3_step(stmt);
78  } while (result == SQLITE_BUSY);
79 
80  return result;
81 }
82 
88 static bool
89 ExecuteRow(sqlite3_stmt *stmt)
90 {
91  int result = ExecuteBusy(stmt);
92  if (result == SQLITE_ROW)
93  return true;
94 
95  if (result != SQLITE_DONE)
96  throw SqliteError(stmt, result, "sqlite3_step() failed");
97 
98  return false;
99 }
100 
107 static void
108 ExecuteCommand(sqlite3_stmt *stmt)
109 {
110  int result = ExecuteBusy(stmt);
111  if (result != SQLITE_DONE)
112  throw SqliteError(stmt, result, "sqlite3_step() failed");
113 }
114 
121 static inline unsigned
122 ExecuteChanges(sqlite3_stmt *stmt)
123 {
124  ExecuteCommand(stmt);
125 
126  return sqlite3_changes(sqlite3_db_handle(stmt));
127 }
128 
135 static inline bool
136 ExecuteModified(sqlite3_stmt *stmt)
137 {
138  return ExecuteChanges(stmt) > 0;
139 }
140 
141 template<typename F>
142 static inline void
143 ExecuteForEach(sqlite3_stmt *stmt, F &&f)
144 {
145  while (true) {
146  int result = ExecuteBusy(stmt);
147  switch (result) {
148  case SQLITE_ROW:
149  f();
150  break;
151 
152  case SQLITE_DONE:
153  return;
154 
155  default:
156  throw SqliteError(stmt, result, "sqlite3_step() failed");
157  }
158  }
159 }
160 
161 #endif
static unsigned ExecuteChanges(sqlite3_stmt *stmt)
Wrapper for ExecuteCommand() that returns the number of rows modified via sqlite3_changes().
Definition: Util.hxx:122
static void ExecuteCommand(sqlite3_stmt *stmt)
Wrapper for ExecuteBusy() that interprets everything other than SQLITE_DONE as error.
Definition: Util.hxx:108
static int ExecuteBusy(sqlite3_stmt *stmt)
Call sqlite3_stmt() repepatedly until something other than SQLITE_BUSY is returned.
Definition: Util.hxx:73
static void Bind(sqlite3_stmt *stmt, unsigned i, const char *value)
Throws SqliteError on error.
Definition: Util.hxx:33
static void ExecuteForEach(sqlite3_stmt *stmt, F &&f)
Definition: Util.hxx:143
static bool ExecuteModified(sqlite3_stmt *stmt)
Wrapper for ExecuteChanges() that returns true if at least one row was modified.
Definition: Util.hxx:136
static bool ExecuteRow(sqlite3_stmt *stmt)
Wrapper for ExecuteBusy() that returns true on SQLITE_ROW.
Definition: Util.hxx:89
#define gcc_unused
Definition: Compiler.h:118
static void BindAll2(gcc_unused sqlite3_stmt *stmt, gcc_unused unsigned i)
Definition: Util.hxx:42
static void BindAll(sqlite3_stmt *stmt, Args &&...args)
Throws SqliteError on error.
Definition: Util.hxx:61