From: AgarFu <ag...@so...> - 2003-07-14 22:57:11
|
-- Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Content-Disposition: inline Hi every one, I'm usin qsqlite in two projects and I have a bug. You can't access views from Qt-designer when you try to add a QDataTable to a form. I have solved this. To do it I had to add [ and ] to field names because sqlite names view fields as they are described in the query and I have a field called: case sex where '0' then 'Male' where '1' then 'Female' end so there is only a way to acces that field, using brackets. here is qsqlite.cpp Thank you for your great work!!!!! -- --------------------------·={ AgarFu }=·------- | ._aasuas,. | | .adZ#X"!""!!X#Xc René Martín Rodríguez | | ._#X?` . ~4XXc Centro Superior de | | .jZ' _ss, ]b/j Informática Universidad | | jX( .7 .. )X[] De La Laguna. | | 3X 3 - ]X(] Grupo Usuarios Linux de | | 3o .],. _, ' 2': Canarias: www.gulic.org | | ]X; -]5s,_sa2"` Sitio en internet: | | 4Z> . "" | | {q, . croasanaso.sytes.net (difunto) | | ."Xa | | -9as ag...@gu... | ------------------------------------------------- -- Content-Type: text/x-c++src; charset="iso-8859-1"; name="qsqlite.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qsqlite.cpp" #include "qsqlite.h" #include <sqlite.h> #include <stdlib.h> #include <qregexp.h> SqliteDriver::SqliteDriver (QObject * parent, const char *name): QSqlDriver(parent,name){ } bool SqliteDriver::open ( const QString & db, const QString &, const QString &, const QString &, int) { char *errmsg=0; bool ok=false; _db=sqlite_open(db.latin1(),0,&errmsg); if (db){ if (SQLITE_OK==sqlite_exec(_db,"PRAGMA empty_result_callbacks = ON;", NULL,NULL,NULL)){ ok=true; } }if (!ok){ setOpen (false); setOpenError(true); setLastError(QSqlError(errmsg,QString::null,QSqlError::Unknown)); return false; }else{ setOpen (true); setOpenError(false); return true; } } void SqliteDriver::close (){ if (_db) sqlite_close(_db); } bool SqliteDriver::hasFeature ( QSqlDriver::DriverFeature feature) const{ switch(feature){ case QSqlDriver::Transactions: case QSqlDriver::QuerySize: case QSqlDriver::Unicode: return true; case QSqlDriver::BLOB: case QSqlDriver::PreparedQueries: case QSqlDriver::NamedPlaceholders: case QSqlDriver::PositionalPlaceholders: return false; } } bool SqliteDriver::beginTransaction (){ int err=sqlite_exec(_db,"BEGIN TRANSACTION;",NULL,NULL,NULL); if (SQLITE_OK==err) return true; else return false; } bool SqliteDriver::commitTransaction (){ int err=sqlite_exec(_db,"COMMIT TRANSACTION;",NULL,NULL,NULL); if (SQLITE_OK==err) return true; else return false; } bool SqliteDriver::rollbackTransaction (){ int err=sqlite_exec(_db,"ROLLBACK TRANSACTION;",NULL,NULL,NULL); if (SQLITE_OK==err) return true; else return false; } /* Dunno what to do here really. Currently, I think I will make it use primary keys.... maybe add support for other indices later. */ QSqlIndex SqliteDriver::primaryIndex ( const QString & tableName ) const{ sqlite_vm *vm; const char *tail; const char **vals; const char **names; int ncol; char* errmsg; QSqlIndex index; QString query ="SELECT sql " "FROM sqlite_master " "WHERE type='table' OR type='view'" "AND name='"+tableName + "';" ; // is there an integer primary key? int err=sqlite_compile(_db, query, &tail, &vm, NULL); if(err != SQLITE_OK){ return QSqlIndex(); } err = sqlite_step(vm,&ncol,&vals, &names); if(err == SQLITE_ROW){ // We found a create statement.. QString sql = vals[0]; sql.replace("\n", " "); QRegExp re("(\\w+)\\s+\\w+(\\s+primary\\s+key)", false); if ( re.search(sql) > -1 ){ // We found a primary key.. QString primary = re.cap(1); QSqlField pkey(primary, QVariant::Int); index.append(pkey); } }else{ qDebug("sqlite_step error"); } sqlite_finalize(vm, NULL); return index; } QSqlQuery SqliteDriver::createQuery () const{ //qDebug ("sqlitedriver::createquery"); return QSqlQuery(new SqliteResult(this)); } QSqlRecord SqliteDriver::record ( const QString & tableName ) const{ //qDebug ("sqlitedriver::record tablename=%s",tableName.latin1()); return recordInfo(tableName).toRecord(); } QSqlRecordInfo SqliteDriver::recordInfo ( const QString & tablename ) const{ //qDebug ("SqliteDriver::recordInfo tablename=%s",tablename.latin1()); sqlite_vm *vm; const char *tail; const char **vals; const char **names; int ntab,ncol; char *errmsg; QSqlFieldInfoList l; QString query; query="PRAGMA table_info("+tablename+");"; int err=sqlite_compile(_db,query, &tail, &vm, &errmsg); if (err == SQLITE_OK){ while ( sqlite_step(vm,&ncol,&vals, &names) == SQLITE_ROW ){ QString cname = vals[1]; cname = "[" + cname + "]"; QVariant::Type t; QVariant defval; QString t1=vals[2]; //Check for integers if ((t1.find ("int")==0) || (t1.find ("tinyint")==0) || (t1.find ("bit")==0) || (t1.find ("bool")==0) || (t1.find ("smallint")==0) || (t1.find ("mediumint")==0) || (t1.find ("integer")==0) || (t1.find ("bigint")==0)){ t=QVariant::Int; } else if ((t1.find ("float")==0) || (t1.find ("double")==0) || (t1.find ("real")==0) || (t1.find ("dec")==0) || (t1.find ("numeric")==0) || (t1.find ("number")==0)){ t=QVariant::Double; } //TODO The date/time types are broken else if ((t1.find ("datetime")==0) || (t1.find ("time")==0) || (t1.find ("date")==0)){ t=QVariant::DateTime; } else{ t=QVariant::String; } defval=QString(vals[4]); defval.cast(t); l << QSqlFieldInfo (cname,t,-1,-1,-1,defval); } }else{ qDebug("error in compile:",errmsg); } err = sqlite_finalize(vm, &errmsg); if( err != SQLITE_OK){ qDebug("error in finalize", errmsg); } return QSqlRecordInfo (l); } QStringList SqliteDriver::tables( const QString& ) const { //qDebug ("Getting list of tables"); sqlite_vm *vm; const char *tail; const char **vals; const char **names; int ntab,ncol; QStringList r; char *errmsg; int err=sqlite_compile(_db,"SELECT name " "FROM sqlite_master " "WHERE type='table' OR type='view'" "ORDER BY name;", &tail, &vm, &errmsg); if (err == SQLITE_OK){ while ( sqlite_step(vm,&ncol,&vals, &names) == SQLITE_ROW ){ r << vals[0]; } sqlite_finalize(vm, NULL); return r; }else{ qDebug ("could not get list of tables: %d, %s",err,errmsg); } } SqliteResult::SqliteResult( const QSqlDriver* d ): QSqlResult(d){ db = static_cast<const SqliteDriver*>(d); } SqliteResult::~SqliteResult(){ } QVariant SqliteResult::data( int i ){ QStringList& row = tab[at()]; if(i < row.count()) return QVariant(row[i]); else return QVariant(); } void SqliteResult::setQuery ( const QString &q ) { //qDebug ("sqliteresult::setquery: %s",q.latin1()); query=q.stripWhiteSpace()+";"; if (q.find("select",0,false)==0) setSelect(true); else setSelect(false); } bool SqliteResult::reset ( const QString& q ){ sqlite_vm* vm; const char** vals; const char** names; query = q; char* errmsg; const char* tail; int err; setQuery(query); tab.clear(); err = sqlite_compile(db->_db,query.latin1(), &tail, &vm, &errmsg); if(err != SQLITE_OK){ qDebug("SQL compile failed:", errmsg); return FALSE; } while(sqlite_step(vm,&cols,&vals, &names) == SQLITE_ROW){ QStringList row; for(int i =0; i < cols; i++){ // copy all the vals.. row.append(vals[i]); } tab.append(row); } sqlite_finalize(vm, NULL); setActive(true); return true; } bool SqliteResult::fetch( int i){ if( i < tab.count() && i>=0 ){ setAt(i); return true; }else{ return false; } } bool SqliteResult::isNull( int i ){ QStringList& row = tab[at()]; if(i < row.count()) return row[i].isEmpty(); else return true; } bool SqliteResult::fetchFirst(){ setAt(0); return true; } bool SqliteResult::fetchLast(){ setAt(tab.count() - 1); return true; } //QSqlRecord SqliteResult::record(){} int SqliteResult::size(){ return tab.count(); } int SqliteResult::numRowsAffected(){ return sqlite_changes(db->_db); } -- Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =2D----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi every one, I'm usin qsqlite in two projects and I have a bug. You can't access views from Qt-designer when you try to add a QDataTable to= a=20 form. I have solved this. To do it I had to add [ and ] to field names because=20 sqlite names view fields as they are described in the query and I have a=20 field called: case sex where '0' then 'Male' where '1' then 'Female' end so there is only a way to acces that field, using brackets. here is qsqlite.cpp Thank you for your great work!!!!! =2D --=20 --------------------------=B7=3D{ AgarFu }=3D=B7------- | ._aasuas,. | | .adZ#X"!""!!X#Xc Ren=E9 Mart=EDn Rodr=EDguez | | ._#X?` . ~4XXc Centro Superior de | | .jZ' _ss, ]b/j Inform=E1tica Universidad | | jX( .7 .. )X[] De La Laguna. | | 3X 3 - ]X(] Grupo Usuarios Linux de | | 3o .],. _, ' 2': Canarias: www.gulic.org | | ]X; -]5s,_sa2"` Sitio en internet: | | 4Z> . "" | | {q, . croasanaso.sytes.net (difunto) | | ."Xa | | -9as ag...@gu... | ------------------------------------------------- =2D----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (GNU/Linux) iD8DBQE/EzTpHfyGHDFT1lYRAm2tAJ9lLBv6LxTgQOPYEqGA/nqfnwjyuQCeIGrT 1QqPXLZ6hzrxLp3tdpdr+uA=3D =3DtnAn =2D----END PGP SIGNATURE----- -- Content-Type: text/x-c++src; charset="iso-8859-1"; name="qsqlite.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qsqlite.cpp" #include "qsqlite.h" #include <sqlite.h> #include <stdlib.h> #include <qregexp.h> SqliteDriver::SqliteDriver (QObject * parent, const char *name): QSqlDriver(parent,name){ } bool SqliteDriver::open ( const QString & db, const QString &, const QString &, const QString &, int) { char *errmsg=0; bool ok=false; _db=sqlite_open(db.latin1(),0,&errmsg); if (db){ if (SQLITE_OK==sqlite_exec(_db,"PRAGMA empty_result_callbacks = ON;", NULL,NULL,NULL)){ ok=true; } }if (!ok){ setOpen (false); setOpenError(true); setLastError(QSqlError(errmsg,QString::null,QSqlError::Unknown)); return false; }else{ setOpen (true); setOpenError(false); return true; } } void SqliteDriver::close (){ if (_db) sqlite_close(_db); } bool SqliteDriver::hasFeature ( QSqlDriver::DriverFeature feature) const{ switch(feature){ case QSqlDriver::Transactions: case QSqlDriver::QuerySize: case QSqlDriver::Unicode: return true; case QSqlDriver::BLOB: case QSqlDriver::PreparedQueries: case QSqlDriver::NamedPlaceholders: case QSqlDriver::PositionalPlaceholders: return false; } } bool SqliteDriver::beginTransaction (){ int err=sqlite_exec(_db,"BEGIN TRANSACTION;",NULL,NULL,NULL); if (SQLITE_OK==err) return true; else return false; } bool SqliteDriver::commitTransaction (){ int err=sqlite_exec(_db,"COMMIT TRANSACTION;",NULL,NULL,NULL); if (SQLITE_OK==err) return true; else return false; } bool SqliteDriver::rollbackTransaction (){ int err=sqlite_exec(_db,"ROLLBACK TRANSACTION;",NULL,NULL,NULL); if (SQLITE_OK==err) return true; else return false; } /* Dunno what to do here really. Currently, I think I will make it use primary keys.... maybe add support for other indices later. */ QSqlIndex SqliteDriver::primaryIndex ( const QString & tableName ) const{ sqlite_vm *vm; const char *tail; const char **vals; const char **names; int ncol; char* errmsg; QSqlIndex index; QString query ="SELECT sql " "FROM sqlite_master " "WHERE type='table' OR type='view'" "AND name='"+tableName + "';" ; // is there an integer primary key? int err=sqlite_compile(_db, query, &tail, &vm, NULL); if(err != SQLITE_OK){ return QSqlIndex(); } err = sqlite_step(vm,&ncol,&vals, &names); if(err == SQLITE_ROW){ // We found a create statement.. QString sql = vals[0]; sql.replace("\n", " "); QRegExp re("(\\w+)\\s+\\w+(\\s+primary\\s+key)", false); if ( re.search(sql) > -1 ){ // We found a primary key.. QString primary = re.cap(1); QSqlField pkey(primary, QVariant::Int); index.append(pkey); } }else{ qDebug("sqlite_step error"); } sqlite_finalize(vm, NULL); return index; } QSqlQuery SqliteDriver::createQuery () const{ //qDebug ("sqlitedriver::createquery"); return QSqlQuery(new SqliteResult(this)); } QSqlRecord SqliteDriver::record ( const QString & tableName ) const{ //qDebug ("sqlitedriver::record tablename=%s",tableName.latin1()); return recordInfo(tableName).toRecord(); } QSqlRecordInfo SqliteDriver::recordInfo ( const QString & tablename ) const{ //qDebug ("SqliteDriver::recordInfo tablename=%s",tablename.latin1()); sqlite_vm *vm; const char *tail; const char **vals; const char **names; int ntab,ncol; char *errmsg; QSqlFieldInfoList l; QString query; query="PRAGMA table_info("+tablename+");"; int err=sqlite_compile(_db,query, &tail, &vm, &errmsg); if (err == SQLITE_OK){ while ( sqlite_step(vm,&ncol,&vals, &names) == SQLITE_ROW ){ QString cname = vals[1]; cname = "[" + cname + "]"; QVariant::Type t; QVariant defval; QString t1=vals[2]; //Check for integers if ((t1.find ("int")==0) || (t1.find ("tinyint")==0) || (t1.find ("bit")==0) || (t1.find ("bool")==0) || (t1.find ("smallint")==0) || (t1.find ("mediumint")==0) || (t1.find ("integer")==0) || (t1.find ("bigint")==0)){ t=QVariant::Int; } else if ((t1.find ("float")==0) || (t1.find ("double")==0) || (t1.find ("real")==0) || (t1.find ("dec")==0) || (t1.find ("numeric")==0) || (t1.find ("number")==0)){ t=QVariant::Double; } //TODO The date/time types are broken else if ((t1.find ("datetime")==0) || (t1.find ("time")==0) || (t1.find ("date")==0)){ t=QVariant::DateTime; } else{ t=QVariant::String; } defval=QString(vals[4]); defval.cast(t); l << QSqlFieldInfo (cname,t,-1,-1,-1,defval); } }else{ qDebug("error in compile:",errmsg); } err = sqlite_finalize(vm, &errmsg); if( err != SQLITE_OK){ qDebug("error in finalize", errmsg); } return QSqlRecordInfo (l); } QStringList SqliteDriver::tables( const QString& ) const { //qDebug ("Getting list of tables"); sqlite_vm *vm; const char *tail; const char **vals; const char **names; int ntab,ncol; QStringList r; char *errmsg; int err=sqlite_compile(_db,"SELECT name " "FROM sqlite_master " "WHERE type='table' OR type='view'" "ORDER BY name;", &tail, &vm, &errmsg); if (err == SQLITE_OK){ while ( sqlite_step(vm,&ncol,&vals, &names) == SQLITE_ROW ){ r << vals[0]; } sqlite_finalize(vm, NULL); return r; }else{ qDebug ("could not get list of tables: %d, %s",err,errmsg); } } SqliteResult::SqliteResult( const QSqlDriver* d ): QSqlResult(d){ db = static_cast<const SqliteDriver*>(d); } SqliteResult::~SqliteResult(){ } QVariant SqliteResult::data( int i ){ QStringList& row = tab[at()]; if(i < row.count()) return QVariant(row[i]); else return QVariant(); } void SqliteResult::setQuery ( const QString &q ) { //qDebug ("sqliteresult::setquery: %s",q.latin1()); query=q.stripWhiteSpace()+";"; if (q.find("select",0,false)==0) setSelect(true); else setSelect(false); } bool SqliteResult::reset ( const QString& q ){ sqlite_vm* vm; const char** vals; const char** names; query = q; char* errmsg; const char* tail; int err; setQuery(query); tab.clear(); err = sqlite_compile(db->_db,query.latin1(), &tail, &vm, &errmsg); if(err != SQLITE_OK){ qDebug("SQL compile failed:", errmsg); return FALSE; } while(sqlite_step(vm,&cols,&vals, &names) == SQLITE_ROW){ QStringList row; for(int i =0; i < cols; i++){ // copy all the vals.. row.append(vals[i]); } tab.append(row); } sqlite_finalize(vm, NULL); setActive(true); return true; } bool SqliteResult::fetch( int i){ if( i < tab.count() && i>=0 ){ setAt(i); return true; }else{ return false; } } bool SqliteResult::isNull( int i ){ QStringList& row = tab[at()]; if(i < row.count()) return row[i].isEmpty(); else return true; } bool SqliteResult::fetchFirst(){ setAt(0); return true; } bool SqliteResult::fetchLast(){ setAt(tab.count() - 1); return true; } //QSqlRecord SqliteResult::record(){} int SqliteResult::size(){ return tab.count(); } int SqliteResult::numRowsAffected(){ return sqlite_changes(db->_db); } -- ---- |