00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "sqliteconnection.h"
00021 #include "sqliteconnection_p.h"
00022 #include "sqlitecursor.h"
00023 #include "sqlitepreparedstatement.h"
00024
00025 #include "sqlite.h"
00026
00027 #ifndef SQLITE2
00028 # include "kexisql.h"
00029 #endif
00030
00031 #include <kexidb/driver.h>
00032 #include <kexidb/cursor.h>
00033 #include <kexidb/error.h>
00034
00035 #include <qfile.h>
00036 #include <qdir.h>
00037
00038 #include <kgenericfactory.h>
00039 #include <kdebug.h>
00040
00041
00042 #undef KexiDBDrvDbg
00043 #define KexiDBDrvDbg if (0) kdDebug()
00044
00045 using namespace KexiDB;
00046
00047 SQLiteConnectionInternal::SQLiteConnectionInternal(Connection *connection)
00048 : ConnectionInternal(connection)
00049 , data(0)
00050 , data_owned(true)
00051 , errmsg_p(0)
00052 , res(SQLITE_OK)
00053 , temp_st(0x10000)
00054 #ifdef SQLITE3
00055 , result_name(0)
00056 #endif
00057 {
00058 }
00059
00060 SQLiteConnectionInternal::~SQLiteConnectionInternal()
00061 {
00062 if (data_owned && data) {
00063 free( data );
00064 data = 0;
00065 }
00066
00067
00068
00069
00070 }
00071
00072 void SQLiteConnectionInternal::storeResult()
00073 {
00074 if (errmsg_p) {
00075 errmsg = errmsg_p;
00076 sqlite_free(errmsg_p);
00077 errmsg_p = 0;
00078 }
00079 #ifdef SQLITE3
00080 errmsg = (data && res!=SQLITE_OK) ? sqlite3_errmsg(data) : 0;
00081 #endif
00082 }
00083
00085 SQLiteConnection::SQLiteConnection( Driver *driver, ConnectionData &conn_data )
00086 : Connection( driver, conn_data )
00087 ,d(new SQLiteConnectionInternal(this))
00088 {
00089 }
00090
00091 SQLiteConnection::~SQLiteConnection()
00092 {
00093 KexiDBDrvDbg << "SQLiteConnection::~SQLiteConnection()" << endl;
00094
00095
00096 destroy();
00097 delete d;
00098 KexiDBDrvDbg << "SQLiteConnection::~SQLiteConnection() ok" << endl;
00099 }
00100
00101 bool SQLiteConnection::drv_connect()
00102 {
00103 KexiDBDrvDbg << "SQLiteConnection::connect()" << endl;
00104 return true;
00105 }
00106
00107 bool SQLiteConnection::drv_disconnect()
00108 {
00109 KexiDBDrvDbg << "SQLiteConnection::disconnect()" << endl;
00110 return true;
00111 }
00112
00113 bool SQLiteConnection::drv_getDatabasesList( QStringList &list )
00114 {
00115
00116 list.append( m_data->fileName() );
00117 return true;
00118 }
00119
00120 bool SQLiteConnection::drv_containsTable( const QString &tableName )
00121 {
00122 bool success;
00123 return resultExists(QString("select name from sqlite_master where type='table' and name LIKE %1")
00124 .arg(driver()->escapeString(tableName)), success) && success;
00125 }
00126
00127 bool SQLiteConnection::drv_getTablesList( QStringList &list )
00128 {
00129 KexiDB::Cursor *cursor;
00130 m_sql = "select lower(name) from sqlite_master where type='table'";
00131 if (!(cursor = executeQuery( m_sql ))) {
00132 KexiDBWarn << "Connection::drv_getTablesList(): !executeQuery()" << endl;
00133 return false;
00134 }
00135 list.clear();
00136 cursor->moveFirst();
00137 while (!cursor->eof() && !cursor->error()) {
00138 list += cursor->value(0).toString();
00139 cursor->moveNext();
00140 }
00141 if (cursor->error()) {
00142 deleteCursor(cursor);
00143 return false;
00144 }
00145 return deleteCursor(cursor);
00146 }
00147
00148 bool SQLiteConnection::drv_createDatabase( const QString &dbName )
00149 {
00150
00151 return drv_useDatabase(dbName);
00152 #if 0
00153 d->data = sqlite_open( QFile::encodeName( m_data->fileName() ), 0,
00154 &d->errmsg_p );
00155 d->storeResult();
00156 return d->data != 0;
00157 #endif
00158 }
00159
00160 bool SQLiteConnection::drv_useDatabase( const QString &dbName, bool *cancelled,
00161 MessageHandler* msgHandler )
00162 {
00163 Q_UNUSED(dbName);
00164 #ifndef KEXI_FUTURE_FEATURES
00165 Q_UNUSED(cancelled);
00166 Q_UNUSED(msgHandler);
00167 #endif
00168
00169 #ifdef SQLITE2
00170 d->data = sqlite_open( QFile::encodeName( m_data->fileName() ), 0,
00171 &d->errmsg_p );
00172 d->storeResult();
00173 return d->data != 0;
00174 #else //SQLITE3
00175
00177 int exclusiveFlag = Connection::isReadOnly() ? SQLITE_OPEN_READONLY : SQLITE_OPEN_WRITE_LOCKED;
00179 int allowReadonly = 1;
00180 # ifdef KEXI_FUTURE_FEATURES
00181 const bool wasReadOnly = Connection::isReadOnly();
00182 # endif
00183
00184 d->res = sqlite3_open(
00185
00186 QFile::encodeName( m_data->fileName() ),
00187 &d->data,
00188 exclusiveFlag,
00189 allowReadonly
00190 );
00191 d->storeResult();
00192
00193 #ifdef KEXI_FUTURE_FEATURES
00194 if (d->res == SQLITE_OK && cancelled && !wasReadOnly && allowReadonly && isReadOnly()) {
00195
00196 if (KMessageBox::Continue !=
00197 askQuestion(
00198 futureI18n("Do you want to open file \"%1\" as read-only?")
00199 .arg(QDir::convertSeparators(m_data->fileName()))
00200 + "\n\n"
00201 + i18n("The file is probably already open on this or another computer.") + " "
00202 + i18n("Could not gain exclusive access for writing the file."),
00203 KMessageBox::WarningContinueCancel, KMessageBox::Continue,
00204 KGuiItem(futureI18n("Open As Read-Only"), "fileopen"), KStdGuiItem::cancel(),
00205 "askBeforeOpeningFileReadOnly", KMessageBox::Notify, msgHandler ))
00206 {
00207 clearError();
00208 *cancelled = true;
00209 return false;
00210 }
00211 }
00212 #endif
00213
00214 if (d->res == SQLITE_CANTOPEN_WITH_LOCKED_READWRITE) {
00215 setError(ERR_ACCESS_RIGHTS,
00216 i18n("The file is probably already open on this or another computer.")+"\n\n"
00217 + i18n("Could not gain exclusive access for reading and writing the file.") + " "
00218 + i18n("Check the file's permissions and whether it is already opened and locked by another application."));
00219 }
00220 else if (d->res == SQLITE_CANTOPEN_WITH_LOCKED_WRITE) {
00221 setError(ERR_ACCESS_RIGHTS,
00222 i18n("The file is probably already open on this or another computer.")+"\n\n"
00223 + i18n("Could not gain exclusive access for writing the file.") + " "
00224 + i18n("Check the file's permissions and whether it is already opened and locked by another application."));
00225 }
00226 return d->res == SQLITE_OK;
00227 #endif
00228 }
00229
00230 bool SQLiteConnection::drv_closeDatabase()
00231 {
00232 if (!d->data)
00233 return false;
00234 sqlite_close(d->data);
00235 d->data = 0;
00236 return true;
00237 }
00238
00239 bool SQLiteConnection::drv_dropDatabase( const QString &dbName )
00240 {
00241 if (QFile(m_data->fileName()).exists() && !QDir().remove(m_data->fileName())) {
00242 setError(ERR_ACCESS_RIGHTS, i18n("Could not remove file \"%1\".")
00243 .arg(QDir::convertSeparators(dbName)) + " "
00244 + i18n("Check the file's permissions and whether it is already opened and locked by another application."));
00245 return false;
00246 }
00247 return true;
00248 }
00249
00250
00251 Cursor* SQLiteConnection::prepareQuery( const QString& statement, uint cursor_options )
00252 {
00253 return new SQLiteCursor( this, statement, cursor_options );
00254 }
00255
00256 Cursor* SQLiteConnection::prepareQuery( QuerySchema& query, uint cursor_options )
00257 {
00258 return new SQLiteCursor( this, query, cursor_options );
00259 }
00260
00261 bool SQLiteConnection::drv_executeSQL( const QString& statement )
00262 {
00263
00264
00265
00266 #ifdef SQLITE_UTF8
00267 d->temp_st = statement.utf8();
00268 #else
00269 d->temp_st = statement.local8Bit();
00270 #endif
00271
00272 d->res = sqlite_exec(
00273 d->data,
00274 (const char*)d->temp_st,
00275 0,
00276 0,
00277 &d->errmsg_p );
00278 d->storeResult();
00279 return d->res==SQLITE_OK;
00280 }
00281
00282 Q_ULLONG SQLiteConnection::drv_lastInsertRowID()
00283 {
00284 return (Q_ULLONG)sqlite_last_insert_rowid(d->data);
00285 }
00286
00287 int SQLiteConnection::serverResult()
00288 {
00289 return d->res==0 ? Connection::serverResult() : d->res;
00290 }
00291
00292 QString SQLiteConnection::serverResultName()
00293 {
00294 QString r =
00295 #ifdef SQLITE2
00296 QString::fromLatin1( sqlite_error_string(d->res) );
00297 #else //SQLITE3
00298 QString::null;
00299 #endif
00300 return r.isEmpty() ? Connection::serverResultName() : r;
00301 }
00302
00303 void SQLiteConnection::drv_clearServerResult()
00304 {
00305 if (!d)
00306 return;
00307 d->res = SQLITE_OK;
00308 #ifdef SQLITE2
00309 d->errmsg_p = 0;
00310 #else
00311
00312 #endif
00313 }
00314
00315 QString SQLiteConnection::serverErrorMsg()
00316 {
00317 return d->errmsg.isEmpty() ? Connection::serverErrorMsg() : d->errmsg;
00318 }
00319
00320 PreparedStatement::Ptr SQLiteConnection::prepareStatement(PreparedStatement::StatementType type,
00321 FieldList& fields)
00322 {
00323
00324 return new SQLitePreparedStatement(type, *d, fields);
00325
00326 }
00327
00328 bool SQLiteConnection::isReadOnly() const
00329 {
00330 #ifdef SQLITE2
00331 return Connection::isReadOnly();
00332 #else
00333 return d->data ? sqlite3_is_readonly(d->data) : false;
00334 #endif
00335 }
00336
00337 #include "sqliteconnection.moc"