Merge pull request #5039 from CEikermann/patch-1
[vuplus_xbmc] / xbmc / dbwrappers / Database.h
1 #pragma once
2
3 /*
4  *      Copyright (C) 2005-2013 Team XBMC
5  *      http://xbmc.org
6  *
7  *  This Program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2, or (at your option)
10  *  any later version.
11  *
12  *  This Program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with XBMC; see the file COPYING.  If not, see
19  *  <http://www.gnu.org/licenses/>.
20  *
21  */
22
23 #include "utils/StdString.h"
24
25 namespace dbiplus {
26   class Database;
27   class Dataset;
28 }
29
30 #include <memory>
31
32 class DatabaseSettings; // forward
33 class CDbUrl;
34 struct SortDescription;
35
36 class CDatabase
37 {
38 public:
39   class Filter
40   {
41   public:
42     Filter() : fields("*") {};
43     Filter(const char *w) : fields("*"), where(w) {};
44     Filter(const std::string &w) : fields("*"), where(w) {};
45     
46     void AppendField(const std::string &strField);
47     void AppendJoin(const std::string &strJoin);
48     void AppendWhere(const std::string &strWhere, bool combineWithAnd = true);
49     void AppendOrder(const std::string &strOrder);
50     void AppendGroup(const std::string &strGroup);
51
52     std::string fields;
53     std::string join;
54     std::string where;
55     std::string order;
56     std::string group;
57     std::string limit;
58   };
59
60   CDatabase(void);
61   virtual ~CDatabase(void);
62   bool IsOpen();
63   void Close();
64   bool Compress(bool bForce=true);
65   void Interupt();
66
67   bool Open(const DatabaseSettings &db);
68
69   void BeginTransaction();
70   virtual bool CommitTransaction();
71   void RollbackTransaction();
72   bool InTransaction();
73
74   CStdString PrepareSQL(CStdString strStmt, ...) const;
75
76   /*!
77    * @brief Get a single value from a table.
78    * @remarks The values of the strWhereClause and strOrderBy parameters have to be FormatSQL'ed when used.
79    * @param strTable The table to get the value from.
80    * @param strColumn The column to get.
81    * @param strWhereClause If set, use this WHERE clause.
82    * @param strOrderBy If set, use this ORDER BY clause.
83    * @return The requested value or an empty string if it wasn't found.
84    */
85   CStdString GetSingleValue(const CStdString &strTable, const CStdString &strColumn, const CStdString &strWhereClause = CStdString(), const CStdString &strOrderBy = CStdString());
86   CStdString GetSingleValue(const CStdString &query);
87
88   /*! \brief Get a single value from a query on a dataset.
89    \param query the query in question.
90    \param ds the dataset to use for the query.
91    \return the value from the query, empty on failure.
92    */
93   std::string GetSingleValue(const std::string &query, std::auto_ptr<dbiplus::Dataset> &ds);
94
95   /*!
96    * @brief Delete values from a table.
97    * @param strTable The table to delete the values from.
98    * @param filter The Filter to apply to this query.
99    * @return True if the query was executed successfully, false otherwise.
100    */
101   bool DeleteValues(const CStdString &strTable, const Filter &filter = Filter());
102
103   /*!
104    * @brief Execute a query that does not return any result.
105    *        Note that if BeginMultipleExecute() has been called, the
106    *        query will be queued until CommitMultipleExecute() is called.
107    * @param strQuery The query to execute.
108    * @return True if the query was executed successfully, false otherwise.
109    * @sa BeginMultipleExecute, CommitMultipleExecute
110    */
111   bool ExecuteQuery(const CStdString &strQuery);
112
113   /*!
114    * @brief Execute a query that returns a result.
115    * @remarks Call m_pDS->close(); to clean up the dataset when done.
116    * @param strQuery The query to execute.
117    * @return True if the query was executed successfully, false otherwise.
118    */
119   bool ResultQuery(const CStdString &strQuery);
120
121   /*!
122    * @brief Start a multiple execution queue. Any ExecuteQuery() function
123    *        following this call will be queued rather than executed until
124    *        CommitMultipleExecute() is performed.
125    *          NOTE: Queries that rely on any queued execute query will not
126    *                function as expected during this period!
127    * @return true if we could start a multiple execution queue, false otherwise.
128    * @sa CommitMultipleExecute, ExecuteQuery
129    */
130   bool BeginMultipleExecute();
131
132   /*!
133    * @brief Commit the multiple execution queue to the database.
134    *        Queries are performed within a transaction, and the transaction
135    *        is rolled back should any one query fail.
136    * @return True if the queries were executed successfully, false otherwise.
137    * @sa BeginMultipleExecute, ExecuteQuery
138    */
139   bool CommitMultipleExecute();
140
141   /*!
142    * @brief Open a new dataset.
143    * @return True if the dataset was created successfully, false otherwise.
144    */
145   bool OpenDS();
146
147   /*!
148    * @brief Put an INSERT or REPLACE query in the queue.
149    * @param strQuery The query to queue.
150    * @return True if the query was added successfully, false otherwise.
151    */
152   bool QueueInsertQuery(const CStdString &strQuery);
153
154   /*!
155    * @brief Commit all queries in the queue.
156    * @return True if all queries were executed successfully, false otherwise.
157    */
158   bool CommitInsertQueries();
159
160   virtual bool GetFilter(CDbUrl &dbUrl, Filter &filter, SortDescription &sorting) { return true; }
161   virtual bool BuildSQL(const CStdString &strBaseDir, const CStdString &strQuery, Filter &filter, CStdString &strSQL, CDbUrl &dbUrl);
162   virtual bool BuildSQL(const CStdString &strBaseDir, const CStdString &strQuery, Filter &filter, CStdString &strSQL, CDbUrl &dbUrl, SortDescription &sorting);
163
164 protected:
165   friend class CDatabaseManager;
166   bool Update(const DatabaseSettings &db);
167
168   void Split(const CStdString& strFileNameAndPath, CStdString& strPath, CStdString& strFileName);
169   uint32_t ComputeCRC(const CStdString &text);
170
171   virtual bool Open();
172
173   /*! \brief Create database tables and analytics as needed.
174    Calls CreateTables() and CreateAnalytics() on child classes.
175    */
176   bool CreateDatabase();
177
178   /* \brief Create tables for the current database schema.
179    Will be called on database creation.
180    */
181   virtual void CreateTables()=0;
182
183   /* \brief Create views, indices and triggers for the current database schema.
184    Will be called on database creation and database update.
185    */
186   virtual void CreateAnalytics()=0;
187
188   /* \brief Update database tables to the current version.
189    Note that analytics (views, indices, triggers) are not present during this
190    function, so don't rely on them.
191    */
192   virtual void UpdateTables(int version) {};
193
194   /* \brief The minimum schema version that we support updating from.
195    */
196   virtual int GetMinSchemaVersion() const { return 0; };
197
198   /* \brief The current schema version.
199    */
200   virtual int GetSchemaVersion() const=0;
201   virtual const char *GetBaseDBName() const=0;
202
203   int GetDBVersion();
204   bool UpdateVersion(const CStdString &dbName);
205
206   bool BuildSQL(const CStdString &strQuery, const Filter &filter, CStdString &strSQL);
207
208   bool m_sqlite; ///< \brief whether we use sqlite (defaults to true)
209
210   std::auto_ptr<dbiplus::Database> m_pDB;
211   std::auto_ptr<dbiplus::Dataset> m_pDS;
212   std::auto_ptr<dbiplus::Dataset> m_pDS2;
213
214 private:
215   void InitSettings(DatabaseSettings &dbSettings);
216   bool Connect(const CStdString &dbName, const DatabaseSettings &db, bool create);
217   void UpdateVersionNumber();
218
219   bool m_bMultiWrite; /*!< True if there are any queries in the queue, false otherwise */
220   unsigned int m_openCount;
221
222   bool m_multipleExecute;
223   std::vector<std::string> m_multipleQueries;
224 };