1 /***************************************************************************
2 * Copyright (C) 2008 by Sverre Rabbelier *
3 * sverre@rabbelier.nl *
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 3 of the License, or *
8 * (at your option) any later version. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
23 #include "SavableManager.h"
24 #include "SelectionMask.h"
25 #include "TableImpl.h"
26 #include "FieldImpl.h"
29 #include "ForeignKey.h"
32 #include "SqliteMgr.h"
33 #include "DatabaseMgr.h"
35 #include "Statements.h"
36 #include "StatementStrings.h"
37 #include "Exceptions.h"
40 SqliteMgr::SqliteMgr()
42 m_db
= DatabaseMgr::Get()->DB();
43 m_odb
= m_db
->grabdb();
49 SqliteMgr::~SqliteMgr()
54 void SqliteMgr::doInsert(SavableManager
* bindable
)
58 TableImpl
* table
= bindable
->getTable().get();
61 sqlite3_stmt
* insert
= getInsertStmt(table
);
64 sqlite3_reset(insert
);
66 if(!table
->hasSingularPrimaryKey())
67 bindable
->bindKeys(m_odb
->db
, insert
);
71 if(table
->hasSingularPrimaryKey())
72 bindable
->parseInsert(m_odb
->db
);
77 void SqliteMgr::doErase(SavableManager
* bindable
)
81 TableImpl
* table
= bindable
->getTable().get();
84 sqlite3_stmt
* erase
= getEraseStmt(table
);
89 bindable
->bindKeys(m_odb
->db
, erase
);
95 void SqliteMgr::doUpdate(SavableManager
* bindable
)
99 TableImpl
* table
= bindable
->getTable().get();
102 sqlite3_stmt
* update
= getUpdateStmt(table
);
105 sqlite3_reset(update
);
107 bindable
->bindUpdate(m_odb
->db
, update
);
113 void SqliteMgr::doSelect(SavableManager
* bindable
)
117 TableImpl
* table
= bindable
->getTable().get();
120 sqlite3_stmt
* select
= getSelectStmt(table
);
123 sqlite3_reset(select
);
125 bindable
->bindKeys(m_odb
->db
, select
);
126 bool row
= doStatement(select
);
128 bindable
->parseSelect(select
);
130 throw RowNotFoundException("SqliteMgr::doSelect(), no row.");
133 void SqliteMgr::doLookup(SavableManager
* bindable
, FieldPtr field
)
138 TableImpl
* table
= bindable
->getTable().get();
141 sqlite3_stmt
* lookup
= getLookupStmt(table
, field
);
144 sqlite3_reset(lookup
);
146 bindable
->bindLookup(m_odb
->db
, lookup
);
147 bool row
= doStatement(lookup
);
150 bindable
->parseLookup(lookup
);
154 throw RowNotFoundException("SqliteMgr::doLookup(), no row.");
157 void SqliteMgr::doForEach(TableImpl
* table
, Actor
& act
)
161 sqlite3_stmt
* forEach
= getForEachStmt(table
);
164 sqlite3_reset(forEach
);
167 for(int i
= 0; good
; i
++)
169 good
= doStatement(forEach
);
171 act
.parseRow(forEach
, table
);
175 void SqliteMgr::doSelectMulti(SelectionMask
* mask
)
179 sqlite3_stmt
* selectMulti
= getSelectMultiStmt(mask
);
182 sqlite3_reset(selectMulti
);
184 mask
->bindSelectMulti(m_odb
->db
, selectMulti
);
187 for(int i
= 0; good
; i
++)
189 good
= doStatement(selectMulti
);
191 mask
->parseRow(selectMulti
);
194 sqlite3_finalize(selectMulti
);
197 void SqliteMgr::commit(TableImpl
* table
)
201 //StatementsPtr statements = getStatements(table);
202 //statements->commit();
204 m_statements
.clear();
208 bool SqliteMgr::doStatement(sqlite3_stmt
* stmt
)
212 int rc
= sqlite3_step(stmt
);
221 throw SqliteError(m_odb
->db
);
224 StatementsPtr
SqliteMgr::getStatements(TableImpl
* table
)
228 StatementsPtr statements
= m_statements
[table
];
232 statements
= StatementsPtr(new Statements());
234 m_statements
[table
] = statements
;
238 StatementStringsPtr
SqliteMgr::getStatementStrings(TableImpl
* table
)
242 StatementStringsPtr statements
= m_statementstrings
[table
];
246 statements
= StatementStringsPtr(new StatementStrings());
248 m_statementstrings
[table
] = statements
;
252 sqlite3_stmt
* SqliteMgr::getInsertStmt(TableImpl
* table
)
256 StatementsPtr statements
= getStatements(table
);
257 sqlite3_stmt
* statement
= statements
->getInsert();
263 StatementStringsPtr statementstrings
= getStatementStrings(table
);
264 cstring statementstring
= statementstrings
->getInsert();
266 if(statementstring
.size() != 0)
268 sql
= statementstring
;
272 sql
.append("INSERT INTO ");
273 sql
.append(table
->tableName());
275 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
277 if(it
!= table
->keybegin())
280 sql
.append(it
->first
);
282 sql
.append(") VALUES(");
283 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
285 if(it
!= table
->keybegin())
288 if(table
->hasSingularPrimaryKey())
295 statementstrings
->setInsert(sql
);
298 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
300 if(errorcode
!= SQLITE_OK
)
301 throw SqliteError(m_odb
->db
);
303 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
305 statements
->setInsert(statement
);
309 sqlite3_stmt
* SqliteMgr::getEraseStmt(TableImpl
* table
)
311 StatementsPtr statements
= getStatements(table
);
312 sqlite3_stmt
* statement
= statements
->getErase();
318 StatementStringsPtr statementstrings
= getStatementStrings(table
);
319 cstring statementstring
= statementstrings
->getErase();
321 if(statementstring
.size() != 0)
323 sql
= statementstring
;
327 sql
.append("DELETE ");
328 sql
.append(table
->tableName());
329 sql
.append(" WHERE ");
330 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
332 if(it
!= table
->keybegin())
335 sql
.append(it
->first
);
340 statementstrings
->setErase(sql
);
343 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
345 if(errorcode
!= SQLITE_OK
)
346 throw SqliteError(m_odb
->db
);
348 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
350 statements
->setErase(statement
);
354 sqlite3_stmt
* SqliteMgr::getUpdateStmt(TableImpl
* table
)
356 StatementsPtr statements
= getStatements(table
);
357 sqlite3_stmt
* statement
= statements
->getUpdate();
363 StatementStringsPtr statementstrings
= getStatementStrings(table
);
364 cstring statementstring
= statementstrings
->getUpdate();
366 if(statementstring
.size() != 0)
368 sql
= statementstring
;
372 sql
.append("UPDATE ");
373 sql
.append(table
->tableName());
375 for(FieldDefVector::const_iterator it
= table
->defbegin(); it
!= table
->defend(); it
++)
377 if(it
!= table
->defbegin())
380 sql
.append((*it
)->getName());
383 sql
.append(" WHERE ");
384 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
386 if(it
!= table
->keybegin())
389 sql
.append(it
->first
);
394 statementstrings
->setUpdate(sql
);
397 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
399 if(errorcode
!= SQLITE_OK
)
400 throw SqliteError(m_odb
->db
);
402 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
404 statements
->setUpdate(statement
);
408 sqlite3_stmt
* SqliteMgr::getSelectStmt(TableImpl
* table
)
410 StatementsPtr statements
= getStatements(table
);
411 sqlite3_stmt
* statement
= statements
->getSelect();
417 StatementStringsPtr statementstrings
= getStatementStrings(table
);
418 cstring statementstring
= statementstrings
->getSelect();
420 if(statementstring
.size() != 0)
422 sql
= statementstring
;
426 sql
.append("SELECT ");
427 for(FieldDefVector::const_iterator it
= table
->defbegin(); it
!= table
->defend(); it
++)
429 if(it
!= table
->defbegin())
432 sql
.append((*it
)->getName());
436 * Prevent queries in the form "SELECT FROM ....", this is for tables that consist of only primary keys.
438 if(!table
->defsize())
441 sql
.append(" FROM ");
442 sql
.append(table
->tableName());
443 sql
.append(" WHERE ");
445 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
447 if(it
!= table
->keybegin())
450 sql
.append(it
->first
);
455 statementstrings
->setSelect(sql
);
458 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
460 if(errorcode
!= SQLITE_OK
)
461 throw SqliteError(m_odb
->db
);
463 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
465 statements
->setSelect(statement
);
469 sqlite3_stmt
* SqliteMgr::getLookupStmt(TableImpl
* table
, FieldPtr field
)
471 StatementsPtr statements
= getStatements(table
);
472 sqlite3_stmt
* statement
= statements
->getLookup(field
);
478 StatementStringsPtr statementstrings
= getStatementStrings(table
);
479 cstring statementstring
= statementstrings
->getLookup(field
);
481 if(statementstring
.size() != 0)
483 sql
= statementstring
;
487 sql
.append("SELECT ");
488 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
490 if(it
!= table
->keybegin())
493 sql
.append(it
->first
);
495 sql
.append(" FROM ");
496 sql
.append(table
->tableName());
497 sql
.append(" WHERE ");
498 sql
.append(field
->getName());
502 statementstrings
->setLookup(field
, sql
);
505 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
507 if(errorcode
!= SQLITE_OK
)
508 throw SqliteError(m_odb
->db
);
510 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
512 statements
->setLookup(field
, statement
);
516 sqlite3_stmt
* SqliteMgr::getForEachStmt(TableImpl
* table
)
518 StatementsPtr statements
= getStatements(table
);
519 sqlite3_stmt
* statement
= statements
->getForEach();
525 StatementStringsPtr statementstrings
= getStatementStrings(table
);
526 cstring statementstring
= statementstrings
->getForEach();
528 if(statementstring
.size() != 0)
530 sql
= statementstring
;
534 sql
.append("SELECT ");
535 bool comspace
= false;
536 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
541 sql
.append(it
->first
);
544 for(FieldDefVector::const_iterator it
= table
->defbegin(); it
!= table
->defend(); it
++)
549 sql
.append((*it
)->getName());
553 sql
.append(" FROM ");
554 sql
.append(table
->tableName());
557 statementstrings
->setForEach(sql
);
560 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
562 if(errorcode
!= SQLITE_OK
)
563 throw SqliteError(m_odb
->db
);
565 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
567 statements
->setForEach(statement
);
571 sqlite3_stmt
* SqliteMgr::getSelectMultiStmt(SelectionMask
* mask
)
576 sqlite3_stmt
* statement
;
578 TableImplPtr table
= mask
->getTable();
581 sql
.append("SELECT ");
582 bool comspace
= false;
583 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
588 sql
.append(it
->first
);
591 for(FieldDefVector::const_iterator it
= table
->defbegin(); it
!= table
->defend(); it
++)
596 sql
.append((*it
)->getName());
601 * Prevent queries in the form "SELECT FROM ....", this is for tables that consist of only primary keys.
603 if(!table
->defsize())
606 sql
.append(" FROM ");
607 sql
.append(table
->tableName());
610 * Allow for queries that retreive data from foreigh tables "SELECT a, b, c, FROM Table INNER JOIN Other ON tableid = fkTable WHERE d = 5;"
612 for(Joins::const_iterator it
= mask
->joinsbegin(); it
!= mask
->joinsend(); it
++)
615 sql
.append(" INNER JOIN ");
616 sql
.append(join
->getJoinTable()->tableName());
618 sql
.append(join
->getNativeKey()->getName());
620 sql
.append(join
->getForeignKey()->getName());
624 * Prevent queries in the form "SELECT a, b, c FROM table WHERE ;", this is for the unmasked selection.
627 sql
.append(" WHERE ");
629 for(Strings::const_iterator it
= mask
->begin(); it
!= mask
->end(); it
++)
631 if(it
!= mask
->begin())
639 printf("SQL: '%s'.\n", sql
.c_str());
641 int errorcode
= sqlite3_prepare_v2(m_odb
->db
, sql
.c_str(), (int)sql
.size(), &statement
, &m_leftover
);
643 if(errorcode
!= SQLITE_OK
)
644 throw SqliteError(m_odb
->db
);
646 Assert(m_leftover
== NULL
|| strlen(m_leftover
) == 0);
652 std::string
SqliteMgr::tableQuery(TableDefPtr table
) const
657 result
.append("SELECT type FROM sqlite_master WHERE tbl_name='");
658 result
.append(table
->tableName());
659 result
.append("' and sql='");
661 result
.append(creationQuery(table
, true));
669 "CREATE TABLE IF NOT EXISTS %s("
670 "%s INTEGER PRIMARY KEY AUTOINCREMENT"
672 ",grantgroup INTEGER RESTRAINT grantgroup DEFAULT 1"
675 std::string
SqliteMgr::creationQuery(TableDefPtr table
, bool verify
) const
682 result
.append("CREATE TABLE ");
684 result
.append("CREATE TABLE IF NOT EXISTS ");
686 result
.append(table
->tableName());
691 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
693 if(table
->hasSingularPrimaryKey() && it
== table
->keybegin())
695 result
.append(it
->first
);
696 result
.append(" INTEGER PRIMARY KEY AUTOINCREMENT, ");
703 result
.append(it
->first
);
704 result
.append(" INTEGER");
708 for(FieldDefVector::const_iterator it
= table
->defbegin(); it
!= table
->defend(); it
++)
713 result
.append(creationString(*it
));
717 if(!table
->hasSingularPrimaryKey())
719 result
.append(", PRIMARY KEY(");
720 for(TableMap::const_iterator it
= table
->keybegin(); it
!= table
->keyend(); it
++)
722 if(it
!= table
->keybegin())
725 result
.append(it
->first
);
738 std::string
SqliteMgr::creationString(FieldDefPtr field
) const
742 std::string result
= field
->getName();
745 result
.append(" TEXT");
747 result
.append(" INTEGER");
749 if(field
->getDefaultValue().size() != 0)
751 result
.append(" RESTRAINT ");
752 result
.append(field
->getName());
753 result
.append(" DEFAULT ");
757 result
.append(field
->getDefaultValue());