Updated to SQLite-CVS 04/28/05 - critical fixes

Changed to UTF8 encoding using Qt functions, should work cross platform without the need to byteswap the data stored in the db file
This commit is contained in:
tabuleiro
2005-04-29 04:26:04 +00:00
parent 4010c15342
commit 33f5538706
41 changed files with 512 additions and 459 deletions

View File

@@ -32,7 +32,7 @@
</sizepolicy>
</property>
<property name="text">
<string>Version 1.2
<string>Version 1.2.1
SQLite Database Browser is an open source, public domain, freeware visual tool used to create, design and edit SQLite 3.x database files.
This program was built with version 3.2.1 of the SQLite engine.

View File

@@ -13,13 +13,13 @@ void addFieldForm::setInitialValues(QString name, QString type)
typeBox->insertItem(type);
QString tString = "";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "text";
tString = "TEXT";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "numeric";
tString = "NUMERIC";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "blob";
tString = "BLOB";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "integer primary key";
tString = "INTEGER PRIMARY KEY";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
}
@@ -27,12 +27,12 @@ void addFieldForm::confirmAddField()
{
QString fieldname = nameLineEdit->text();
if (fieldname.isEmpty()) {
QMessageBox::information( this, applicationName, "Field name can not be empty" );
return;
QMessageBox::information( this, applicationName, "Field name can not be empty" );
return;
}
if (fieldname.contains(" ")>0) {
QMessageBox::warning( this, applicationName, "Spaces are not allowed in the field name" );
return;
QMessageBox::warning( this, applicationName, "Spaces are not allowed in the field name" );
return;
}
fname = fieldname;
ftype = typeBox->currentText();
@@ -44,7 +44,7 @@ void addFieldForm::getCustomType()
addFieldTypeForm * addForm = new addFieldTypeForm( this, "addfieldtype", TRUE );
if (addForm->exec())
{
QString nospaces = addForm->typeNameEdit->text().remove(" ");
setInitialValues(nameLineEdit->text(),nospaces );
QString nospaces = addForm->typeNameEdit->text().remove(" ");
setInitialValues(nameLineEdit->text(),nospaces );
}
}

View File

@@ -13,13 +13,13 @@ void editFieldForm::setInitialValues(QString name, QString type)
typeBox->insertItem(type);
QString tString = "";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "text";
tString = "TEXT";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "numeric";
tString = "NUMERIC";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "blob";
tString = "BLOB";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
tString = "integer primary key";
tString = "INTEGER PRIMARY KEY";
if (type.compare(tString)!=0) typeBox->insertItem(tString);
}
@@ -27,7 +27,7 @@ void editFieldForm::confirmEdit()
{
QString fieldname = nameLineEdit->text();
if (fieldname.isEmpty()) {
QMessageBox::information( this, applicationName, "Field name can not be empty" );
QMessageBox::information( this, applicationName, "Field name can not be empty" );
return;
}
if (fieldname.contains(" ")>0) {

View File

@@ -286,12 +286,13 @@ void mainForm::closeEvent( QCloseEvent * )
void mainForm::addRecord()
{
if (db.addRecord()){
populateTable(db.curBrowseTableName);
//added record will be the last one in view
recAtTop = ((db.getRecordCount()-1)/recsPerView)*recsPerView;
updateTableView(db.getRecordCount()-recAtTop-1);
}else{
QMessageBox::information( this, applicationName,
"Please select a table first" );
"Error adding record, make sure a table is selected" );
}
}
@@ -353,7 +354,7 @@ void mainForm::updateTableView(int lineToSelect)
QString content = *it;
QString firstline = content.section( '\n', 0,0 );
if (content.length()>MAX_DISPLAY_LENGTH)
{
{
firstline.truncate(MAX_DISPLAY_LENGTH);
firstline.append("...");
}
@@ -459,63 +460,29 @@ void mainForm::browseFind(bool open)
this, SLOT( lookfor(const QString&, const QString&, const QString&) ) );
connect( findWin, SIGNAL( showrecord(int) ),this, SLOT( showrecord(int) ) );
connect( findWin, SIGNAL( goingAway() ),this, SLOT( browseFindAway() ) );
}
findWin->resetFields(db.getTableFields(db.curBrowseTableName));
findWin->show();
}
findWin->resetFields(db.getTableFields(db.curBrowseTableName));
findWin->show();
} else {
if (findWin){
findWin->hide();
}
if (findWin){
findWin->hide();
}
}
}
void mainForm::browseFindAway()
{
buttonFind->toggle();
buttonFind->toggle();
}
void mainForm::lookfor( const QString & wfield, const QString & woperator, const QString & wsearchterm )
{
if (!db.isOpen()){
QMessageBox::information( this, applicationName, "There is no database opened. Please open or create a new database file." );
return;
}
//we may need to modify woperator and wsearchterm, so use copies
QString * finaloperator = new QString(woperator);
QString * finalsearchterm = new QString(wsearchterm);
//special case for CONTAINS operator: use LIKE and surround the search word with % characters
if (woperator.compare("contains")==0){
finaloperator = new QString("LIKE");
QString newsearchterm = "%";
newsearchterm.append(wsearchterm);
newsearchterm.append("%");
finalsearchterm = new QString( newsearchterm);
QMessageBox::information( this, applicationName, "There is no database opened. Please open or create a new database file." );
return;
}
QApplication::setOverrideCursor( waitCursor, TRUE );
QString statement = "SELECT rowid, ";
statement.append(wfield);
statement.append(" FROM ");
statement.append( db.curBrowseTableName);
statement.append(" WHERE ");
statement.append(wfield);
statement.append(" ");
statement.append(*finaloperator);
statement.append(" ");
//searchterm needs to be quoted if it is not a number
bool ok = false;
wsearchterm.toDouble(&ok);
if (!ok) wsearchterm.toInt(&ok, 10);
if (!ok) {//not a number, quote it
char * formSQL = sqlite3_mprintf("%Q",static_cast<const char*>((*finalsearchterm).utf8()));
statement.append(formSQL);
if (formSQL) sqlite3_free(formSQL);
} else {//append the number, unquoted
statement.append(*finalsearchterm);
}
statement.append(" ORDER BY rowid; ");
resultMap res = db.getFindResults(statement);
resultMap res = db.getFindResults(wfield, woperator, wsearchterm);
findWin->showResults(res);
QApplication::restoreOverrideCursor();
}
@@ -537,8 +504,8 @@ void mainForm::createTable()
if ( tableForm->exec() ) {
if (!db.executeSQL(tableForm->createStatement)){
QString error = "Error: could not create the table. Message from database engine: ";
error.append(db.lastErrorMessage);
QMessageBox::warning( this, applicationName, error );
error.append(db.lastErrorMessage);
QMessageBox::warning( this, applicationName, error );
} else {
populateStructure();
resetBrowser();
@@ -559,12 +526,12 @@ void mainForm::createIndex()
if ( indexForm->exec() ) {
if (!db.executeSQL(indexForm->createStatement)){
QString error = "Error: could not create the index. Message from database engine: ";
error.append(db.lastErrorMessage);
QMessageBox::warning( this, applicationName, error );
} else {
populateStructure();
resetBrowser();
}
error.append(db.lastErrorMessage);
QMessageBox::warning( this, applicationName, error );
} else {
populateStructure();
resetBrowser();
}
}
}
@@ -573,13 +540,13 @@ void mainForm::compact()
{
QApplication::setOverrideCursor( waitCursor, TRUE );
if (db.isOpen()){
if (!db.compact()){
QString error = "Error: could not compact the database file. Message from database engine: ";
error.append(db.lastErrorMessage);
QMessageBox::warning( this, applicationName, error );
} else {
QMessageBox::warning( this, applicationName, "Database compacted" );
}
if (!db.compact()){
QString error = "Error: could not compact the database file. Message from database engine: ";
error.append(db.lastErrorMessage);
QMessageBox::warning( this, applicationName, error );
} else {
QMessageBox::warning( this, applicationName, "Database compacted" );
}
}
db.open(db.curDBFilename);
populateStructure();
@@ -732,9 +699,9 @@ void mainForm::updateRecordText(int row, int col, QString newtext)
QString content = *cv ;
QString firstline = content.section( '\n', 0,0 );
if (content.length()>14)
if (content.length()>MAX_DISPLAY_LENGTH )
{
firstline.truncate(14);
firstline.truncate(MAX_DISPLAY_LENGTH );
firstline.append("...");
}
dataTable->setText( row - recAtTop, col, firstline);
@@ -796,7 +763,7 @@ void mainForm::executeQuery()
//log the query
db.logSQL(query, kLogMsg_User);
sqlite3_stmt *vm;
const void *tail;
const char *tail;
int ncol;
int err=0;
@@ -808,44 +775,45 @@ void mainForm::executeQuery()
queryResultListView->removeColumn(0);
}
err=sqlite3_prepare16(db._db,query.ucs2(),query.length(),&vm,&tail);
if (err == SQLITE_OK){
db.setDirty(true);
int rownum = 0;
QListViewItem * lasttbitem = 0;
bool mustCreateColumns = true;
while ( sqlite3_step(vm) == SQLITE_ROW ){
//r.clear()
QListViewItem * tbitem = new QListViewItem( queryResultListView, lasttbitem);
//setup num of cols here for display grid
if (mustCreateColumns)
{
ncol = sqlite3_data_count(vm);
for (int e=0; e<ncol; e++)
queryResultListView->addColumn("");
mustCreateColumns = false;
}
for (int e=0; e<ncol; e++){
QString rv(StringFromUTF16(sqlite3_column_text16(vm, e)));
//show it here
QString firstline = rv.section( '\n', 0,0 );
if (firstline.length()>MAX_DISPLAY_LENGTH)
{
firstline.truncate(MAX_DISPLAY_LENGTH);
firstline.append("...");
}
tbitem->setText( e, firstline);
lasttbitem = tbitem;
rownum++;
}
}
err=sqlite3_prepare(db._db,query.utf8(),-1,&vm,&tail);
if (err == SQLITE_OK){
db.setDirty(true);
int rownum = 0;
QListViewItem * lasttbitem = 0;
bool mustCreateColumns = true;
while ( sqlite3_step(vm) == SQLITE_ROW ){
//r.clear()
QListViewItem * tbitem = new QListViewItem( queryResultListView, lasttbitem);
//setup num of cols here for display grid
if (mustCreateColumns)
{
ncol = sqlite3_data_count(vm);
for (int e=0; e<ncol; e++)
queryResultListView->addColumn("");
mustCreateColumns = false;
}
for (int e=0; e<ncol; e++){
QString rv(QString::fromUtf8((const char *) sqlite3_column_text(vm, e)));
//show it here
QString firstline = rv.section( '\n', 0,0 );
if (firstline.length()>MAX_DISPLAY_LENGTH)
{
firstline.truncate(MAX_DISPLAY_LENGTH);
firstline.append("...");
}
tbitem->setText( e, firstline);
lasttbitem = tbitem;
rownum++;
}
}
sqlite3_finalize(vm);
}else{
lastErrorMessage = QString (sqlite3_errmsg(db._db));
}
queryErrorLineEdit->setText(lastErrorMessage);
queryResultListView->setResizeMode(QListView::AllColumns);
}
@@ -853,8 +821,8 @@ void mainForm::mainTabSelected(const QString & tabname)
{
if ((mainTab->currentPageIndex ()==0)||(mainTab->currentPageIndex ()==1))
{
populateStructure();
resetBrowser();
populateStructure();
resetBrowser();
}
}
@@ -862,9 +830,9 @@ void mainForm::mainTabSelected(const QString & tabname)
void mainForm::toggleLogWindow( bool enable )
{
if (enable){
logWin->show();
logWin->show();
} else {
logWin->hide();
logWin->hide();
}
}
@@ -872,37 +840,37 @@ void mainForm::toggleLogWindow( bool enable )
void mainForm::importTableFromCSV()
{
if (!db.isOpen()){
QMessageBox::information( this, applicationName, "There is no database opened. Please open or create a new database file first." );
return;
QMessageBox::information( this, applicationName, "There is no database opened. Please open or create a new database file first." );
return;
}
if (db.getDirty())
{
QString msg = "Database needs to be saved before the import operation.\nSave current changes and continue?";
if (QMessageBox::question( this, applicationName ,msg, QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
bool done(false);
do {
if ( db.save() )
done = true;
else {
QString error = "Error: could not save the database.\nMessage from database engine: ";
error.append(db.lastErrorMessage);
switch ( QMessageBox::warning( this, applicationName, error, QMessageBox::Retry|QMessageBox::Default, QMessageBox::Cancel|QMessageBox::Escape, QMessageBox::Ignore) ) {
case QMessageBox::Retry:
break;
case QMessageBox::Ignore:
db.revert();
done = true;
break;
case QMessageBox::Cancel:
return;
}
}
} while ( !done );
} else {
return;
}
QString msg = "Database needs to be saved before the import operation.\nSave current changes and continue?";
if (QMessageBox::question( this, applicationName ,msg, QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
bool done(false);
do {
if ( db.save() )
done = true;
else {
QString error = "Error: could not save the database.\nMessage from database engine: ";
error.append(db.lastErrorMessage);
switch ( QMessageBox::warning( this, applicationName, error, QMessageBox::Retry|QMessageBox::Default, QMessageBox::Cancel|QMessageBox::Escape, QMessageBox::Ignore) ) {
case QMessageBox::Retry:
break;
case QMessageBox::Ignore:
db.revert();
done = true;
break;
case QMessageBox::Cancel:
return;
}
}
} while ( !done );
} else {
return;
}
}
QString wFile = QFileDialog::getOpenFileName(
@@ -914,99 +882,99 @@ void mainForm::importTableFromCSV()
if (QFile::exists(wFile) )
{
importCSVForm * csvForm = new importCSVForm( this, "importcsv", TRUE );
csvForm->initialize(wFile, &db);
if ( csvForm->exec() ) {
populateStructure();
resetBrowser();
QMessageBox::information( this, applicationName, "Import completed" );
}
importCSVForm * csvForm = new importCSVForm( this, "importcsv", TRUE );
csvForm->initialize(wFile, &db);
if ( csvForm->exec() ) {
populateStructure();
resetBrowser();
QMessageBox::information( this, applicationName, "Import completed" );
}
}
}
void mainForm::exportTableToCSV()
{
if (!db.isOpen()){
QMessageBox::information( this, applicationName, "There is no database opened to export" );
return;
QMessageBox::information( this, applicationName, "There is no database opened to export" );
return;
}
exportTableCSVForm * exportForm = new exportTableCSVForm( this, "export table", TRUE );
exportForm->populateOptions( db.getTableNames());
if ( exportForm->exec() ) {
//qDebug(exportForm->option);
//load our table
db.browseTable(exportForm->option);
QString fileName = QFileDialog::getSaveFileName(
//qDebug(exportForm->option);
//load our table
db.browseTable(exportForm->option);
QString fileName = QFileDialog::getSaveFileName(
"",
"Text files (*.csv *txt)",
this,
"save file dialog"
"Choose a filename to export data" );
if (fileName)
{
QFile file(fileName);
if ( file.open( IO_WriteOnly ) )
{
char quote = '"';
char sep = ',';
char feed = 10;
int colNum = 0;
int colCount = 0;
QTextStream stream( &file );
//fieldnames on first row
QStringList fields = db.browseFields;
colCount = fields.count();
for ( QStringList::Iterator ct = fields.begin(); ct != fields.end(); ++ct ) {
stream << quote;
stream << *ct;
stream << quote;
colNum++;
if (colNum<colCount)
{
stream << sep;
} else {
stream << feed;
colNum = 0;
}
}
//now export data
rowList tab = db.browseRecs;
rowList::iterator rt;
//int dcols =0;
QString rowLabel;
for ( rt = tab.at(0); rt !=tab.end(); ++rt )
{
for ( QStringList::Iterator it = (*rt).begin(); it != (*rt).end(); ++it ) {
//skip first one (the rowid)
if (it!=(*rt).begin()){
QString content = *it;
stream<< quote;
QChar qquote = quote;
content.replace(quote, QString(qquote).append(qquote));
stream<< content;
stream<< quote;
colNum++;
if (colNum<colCount)
{
stream << sep;
} else {
stream << feed;
colNum = 0;
}
}
}
}
if (fileName)
{
QFile file(fileName);
if ( file.open( IO_WriteOnly ) )
{
char quote = '"';
char sep = ',';
char feed = 10;
int colNum = 0;
int colCount = 0;
QTextStream stream( &file );
//fieldnames on first row
QStringList fields = db.browseFields;
colCount = fields.count();
for ( QStringList::Iterator ct = fields.begin(); ct != fields.end(); ++ct ) {
stream << quote;
stream << *ct;
stream << quote;
colNum++;
if (colNum<colCount)
{
stream << sep;
} else {
stream << feed;
colNum = 0;
}
}
//now export data
rowList tab = db.browseRecs;
rowList::iterator rt;
//int dcols =0;
QString rowLabel;
for ( rt = tab.at(0); rt !=tab.end(); ++rt )
{
for ( QStringList::Iterator it = (*rt).begin(); it != (*rt).end(); ++it ) {
//skip first one (the rowid)
if (it!=(*rt).begin()){
QString content = *it;
stream<< quote;
QChar qquote = quote;
content.replace(quote, QString(qquote).append(qquote));
stream<< content;
stream<< quote;
colNum++;
if (colNum<colCount)
{
stream << sep;
} else {
stream << feed;
colNum = 0;
}
}
}
}
file.close();
QMessageBox::information( this, applicationName, "Export completed" );
}
}
populateStructure();
resetBrowser();
file.close();
QMessageBox::information( this, applicationName, "Export completed" );
}
}
populateStructure();
resetBrowser();
}
}
@@ -1021,14 +989,14 @@ void mainForm::dbState( bool dirty )
void mainForm::fileSave()
{
if (db.isOpen()){
do {
if ( !db.save() ) {
QString error = "Error: could not save the database.\nMessage from database engine: ";
error.append(db.lastErrorMessage);
if ( QMessageBox::warning( this, applicationName, error, QMessageBox::Ok, QMessageBox::Retry|QMessageBox::Default) != QMessageBox::Retry )
break;
}
} while ( db.getDirty() );
do {
if ( !db.save() ) {
QString error = "Error: could not save the database.\nMessage from database engine: ";
error.append(db.lastErrorMessage);
if ( QMessageBox::warning( this, applicationName, error, QMessageBox::Ok, QMessageBox::Retry|QMessageBox::Default) != QMessageBox::Retry )
break;
}
} while ( db.getDirty() );
}
}
@@ -1036,15 +1004,15 @@ void mainForm::fileSave()
void mainForm::fileRevert()
{
if (db.isOpen()){
QString msg = "Are you sure you want to undo all changes made to the database file \n ";
msg.append(db.curDBFilename);
msg.append(" since the last save?");
if (QMessageBox::question( this, applicationName ,msg, QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
db.revert();
populateStructure();
resetBrowser();
}
QString msg = "Are you sure you want to undo all changes made to the database file \n ";
msg.append(db.curDBFilename);
msg.append(" since the last save?");
if (QMessageBox::question( this, applicationName ,msg, QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
db.revert();
populateStructure();
resetBrowser();
}
}
}
@@ -1052,8 +1020,8 @@ void mainForm::fileRevert()
void mainForm::exportDatabaseToSQL()
{
if (!db.isOpen()){
QMessageBox::information( this, applicationName, "There is no database opened to export" );
return;
QMessageBox::information( this, applicationName, "There is no database opened to export" );
return;
}
QString fileName = QFileDialog::getSaveFileName(
@@ -1063,15 +1031,15 @@ void mainForm::exportDatabaseToSQL()
"save file dialog"
"Choose a filename to export" );
if (fileName)
{
if (!db.dump(fileName))
{
QMessageBox::information( this, applicationName, "Could not create export file" );
} else {
QMessageBox::information( this, applicationName, "Export completed" );
}
}
if (fileName)
{
if (!db.dump(fileName))
{
QMessageBox::information( this, applicationName, "Could not create export file" );
} else {
QMessageBox::information( this, applicationName, "Export completed" );
}
}
}
@@ -1085,39 +1053,39 @@ void mainForm::importDatabaseFromSQL()
"Choose a file to import" );
if (fileName)
{
QString msg = "Do you want to create a new database file to hold the imported data?\nIf you answer NO we will attempt to import data in the .sql file to the current database.";
if (QMessageBox::question( this, applicationName ,msg, QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
QString newDBfile = QFileDialog::getSaveFileName(
"",
"",
this,
"create file dialog"
"Choose a filename to save under" );
if (QFile::exists(newDBfile) )
{
QString err = "File ";
err.append(newDBfile);
err.append(" already exists. Please choose a different name");
QMessageBox::information( this, applicationName ,err);
return;
}
if (!fileName.isNull())
{
db.create(newDBfile);
}
{
QString msg = "Do you want to create a new database file to hold the imported data?\nIf you answer NO we will attempt to import data in the .sql file to the current database.";
if (QMessageBox::question( this, applicationName ,msg, QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
QString newDBfile = QFileDialog::getSaveFileName(
"",
"",
this,
"create file dialog"
"Choose a filename to save under" );
if (QFile::exists(newDBfile) )
{
QString err = "File ";
err.append(newDBfile);
err.append(" already exists. Please choose a different name");
QMessageBox::information( this, applicationName ,err);
return;
}
if (!fileName.isNull())
{
db.create(newDBfile);
}
}
int lineErr;
if (!db.reload(fileName, &lineErr))
{
QMessageBox::information( this, applicationName, QString("Error importing data at line %1").arg(lineErr) );
}
else
{
QMessageBox::information( this, applicationName, "Import completed" );
}
populateStructure();
resetBrowser();
}
int lineErr;
if (!db.reload(fileName, &lineErr))
{
QMessageBox::information( this, applicationName, QString("Error importing data at line %1").arg(lineErr) );
}
else
{
QMessageBox::information( this, applicationName, "Import completed" );
}
populateStructure();
resetBrowser();
}
}

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.2 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: alter.c,v 1.3 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: attach.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"

View File

@@ -14,7 +14,7 @@
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: auth.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: btree.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to

View File

@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** @(#) $Id: btree.h,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

View File

@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
** $Id: build.c,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: build.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

View File

@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.2 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: date.c,v 1.3 2005-04-29 04:26:02 tabuleiro Exp $
**
** NOTES:
**

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: delete.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -230,7 +230,7 @@ void sqlite3DeleteFrom(
/* Begin the database scan
*/
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
if( pWInfo==0 ) goto delete_from_cleanup;
/* Remember the rowid of every item to be deleted.
@@ -264,8 +264,8 @@ void sqlite3DeleteFrom(
*/
if( triggers_exist ){
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
if( !isView ){
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
sqlite3OpenTableForReading(v, iCur, pTab);
}
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
@@ -278,7 +278,7 @@ void sqlite3DeleteFrom(
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
-1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
addr);
addr);
}
if( !isView ){
@@ -312,7 +312,7 @@ void sqlite3DeleteFrom(
}
(void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
addr);
addr);
}
/* End of the delete loop */

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are not a part of the official
** SQLite API. These routines are unsupported.
**
** $Id: experimental.c,v 1.1 2005-03-23 14:56:41 jmiltner Exp $
** $Id: experimental.c,v 1.2 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"

View File

@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.4 2005-04-05 04:14:52 tabuleiro Exp $
** $Id: expr.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -529,7 +529,6 @@ Select *sqlite3SelectDup(Select *p){
pNew->iLimit = -1;
pNew->iOffset = -1;
pNew->ppOpenTemp = 0;
pNew->pFetch = 0;
pNew->isResolved = p->isResolved;
pNew->isAgg = p->isAgg;
return pNew;

View File

@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** $Id: func.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

View File

@@ -12,7 +12,7 @@
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** $Id: hash.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

View File

@@ -12,7 +12,7 @@
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** $Id: hash.h,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** $Id: insert.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.2 2005-04-05 04:14:53 tabuleiro Exp $
** $Id: legacy.c,v 1.3 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** $Id: main.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -531,8 +531,9 @@ int sqlite3_close(sqlite3 *db){
#ifndef SQLITE_OMIT_GLOBALRECOVER
{
sqlite3 *pPrev = pDbList;
sqlite3 *pPrev;
sqlite3OsEnterMutex();
pPrev = pDbList;
while( pPrev && pPrev->pNext!=db ){
pPrev = pPrev->pNext;
}

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** @(#) $Id: pager.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@@ -13,7 +13,7 @@
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.4 2005-04-05 04:14:53 tabuleiro Exp $
** @(#) $Id: pager.h,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
/*
@@ -23,12 +23,15 @@
# define SQLITE_DEFAULT_PAGE_SIZE 1024
#endif
/* Maximum page size. The upper bound on this value is 65536 (a limit
** imposed by the 2-byte size of cell array pointers.) The
** maximum page size determines the amount of stack space allocated
** by many of the routines in pager.c and btree.c On embedded architectures
** or any machine where memory and especially stack memory is limited,
** one may wish to chose a smaller value for the maximum page size.
/* Maximum page size. The upper bound on this value is 32768. This a limit
** imposed by necessity of storing the value in a 2-byte unsigned integer
** and the fact that the page size must be a power of 2.
**
** This value is used to initialize certain arrays on the stack at
** various places in the code. On embedded machines where stack space
** is limited and the flexibility of having large pages is not needed,
** it makes good sense to reduce the maximum page size to something more
** reasonable, like 1024.
*/
#ifndef SQLITE_MAX_PAGE_SIZE
# define SQLITE_MAX_PAGE_SIZE 8192

View File

@@ -2528,7 +2528,7 @@ static void yy_reduce(
#line 2530 "parse.c"
break;
case 158:
#line 552 "parse.y"
#line 549 "parse.y"
{sqlite3Update(pParse,yymsp[-3].minor.yy439,yymsp[-1].minor.yy322,yymsp[0].minor.yy418,yymsp[-4].minor.yy328);}
#line 2535 "parse.c"
break;

View File

@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.4 2005-04-05 04:14:59 tabuleiro Exp $
** $Id: pragma.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@@ -15,7 +15,7 @@
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.4 2005-04-05 04:15:00 tabuleiro Exp $
** $Id: random.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.4 2005-04-05 04:15:00 tabuleiro Exp $
** $Id: select.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -2760,7 +2760,7 @@ int sqlite3Select(
/* Begin the database scan
*/
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,
pGroupBy ? 0 : &pOrderBy, p->pFetch);
pGroupBy ? 0 : &pOrderBy);
if( pWInfo==0 ) goto select_end;
/* Use the standard inner loop if we are not dealing with

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite3.h,v 1.2 2005-04-05 04:15:01 tabuleiro Exp $
** @(#) $Id: sqlite3.h,v 1.3 2005-04-29 04:26:02 tabuleiro Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -1208,6 +1208,17 @@ int sqlite3_sleep(int);
*/
int sqlite3_expired(sqlite3_stmt*);
/*
** Move all bindings from the first prepared statement over to the second.
** This routine is useful, for example, if the first prepared statement
** fails with an SQLITE_SCHEMA error. The same SQL can be prepared into
** the second prepared statement then all of the bindings transfered over
** to the second statement before the first statement is finalized.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
/*
** If the following global variable is made to point to a
** string which is the name of a directory, then all temporary files
@@ -1224,7 +1235,7 @@ extern char *sqlite3_temp_directory;
** This function is called to recover from a malloc() failure that occured
** within the SQLite library. Normally, after a single malloc() fails the
** library refuses to function (all major calls return SQLITE_NOMEM).
** This function library state so that it can be used again.
** This function restores the library state so that it can be used again.
**
** All existing statements (sqlite3_stmt pointers) must be finalized or
** reset before this call is made. Otherwise, SQLITE_BUSY is returned.

View File

@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** @(#) $Id: sqliteInt.h,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -317,7 +317,6 @@ extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
typedef struct Column Column;
typedef struct Table Table;
typedef struct Index Index;
typedef struct Instruction Instruction;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct Parse Parse;
@@ -339,7 +338,6 @@ typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
typedef struct NameContext NameContext;
typedef struct Fetch Fetch;
/*
** Each database file to be accessed by the system is an instance
@@ -1049,7 +1047,6 @@ struct Select {
Expr *pOffset; /* OFFSET expression. NULL means not used. */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
IdList **ppOpenTemp; /* OP_OpenTemp addresses used by multi-selects */
Fetch *pFetch; /* If this stmt is part of a FETCH command */
u8 isResolved; /* True once sqlite3SelectResolve() has run. */
u8 isAgg; /* True if this is an aggregate query */
};
@@ -1419,7 +1416,7 @@ void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*);
void sqlite3OpenTable(Vdbe*, int iCur, Table*, int);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, Fetch*);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);

View File

@@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: tokenize.c,v 1.5 2005-04-29 04:26:02 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: update.c,v 1.5 2005-04-29 04:26:03 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -267,7 +267,7 @@ void sqlite3Update(
/* Begin the database scan
*/
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
if( pWInfo==0 ) goto update_cleanup;
/* Remember the index of every item to be updated.
@@ -297,13 +297,13 @@ void sqlite3Update(
*/
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
/* Open a cursor and make it point to the record that is
** being updated.
*/
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
if( !isView ){
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
/* Open a cursor and make it point to the record that is
** being updated.
*/
sqlite3OpenTableForReading(v, iCur, pTab);
}
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);

View File

@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.2 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: utf.c,v 1.3 2005-04-29 04:26:03 tabuleiro Exp $
**
** Notes on UTF-8:
**

View File

@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: util.c,v 1.5 2005-04-29 04:26:03 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>

View File

@@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: vacuum.c,v 1.5 2005-04-29 04:26:03 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: vdbe.c,v 1.5 2005-04-29 04:26:03 tabuleiro Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1316,7 +1316,7 @@ case OP_AddImm: { /* no-push */
** greater than its current value if P1==1.
*/
case OP_ForceInt: { /* no-push */
int v;
i64 v;
assert( pTos>=p->aStack );
applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
@@ -4117,8 +4117,13 @@ case OP_SortPut: { /* no-push */
if( Dynamicify(pTos, db->enc) ) goto no_mem;
pSorter = sqliteMallocRaw( sizeof(Sorter) );
if( pSorter==0 ) goto no_mem;
pSorter->pNext = p->pSort;
p->pSort = pSorter;
pSorter->pNext = 0;
if( p->pSortTail ){
p->pSortTail->pNext = pSorter;
}else{
p->pSort = pSorter;
}
p->pSortTail = pSorter;
assert( pTos->flags & MEM_Dyn );
pSorter->nKey = pTos->n;
pSorter->zKey = pTos->z;

View File

@@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: vdbe.h,v 1.5 2005-04-29 04:26:04 tabuleiro Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_

View File

@@ -314,6 +314,7 @@ struct Vdbe {
int nCursor; /* Number of slots in apCsr[] */
Cursor **apCsr; /* One element of this array for each open cursor */
Sorter *pSort; /* A linked list of objects to be sorted */
Sorter *pSortTail; /* Last element on the pSort list */
int nVar; /* Number of entries in aVar[] */
Mem *aVar; /* Values for the OP_Variable opcode. */
char **azVar; /* Name of variables */

View File

@@ -622,3 +622,26 @@ int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
}
return 0;
}
/* EXPERIMENTAL
**
** Transfer all bindings from the first statement over to the second.
** If the two statements contain a different number of bindings, then
** an SQLITE_ERROR is returned.
*/
int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
int i, rc = SQLITE_OK;
if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT)
|| (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){
return SQLITE_MISUSE;
}
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
}
return rc;
}

View File

@@ -191,7 +191,7 @@ static int opcodeNoPush(u8 op){
** error if someone builds with an awk that uses (for example) 32-bit
** IEEE floats.
*/
static u32 masks[5] = {
static const u32 masks[5] = {
NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16),
NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16),
NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16),
@@ -779,6 +779,7 @@ void sqlite3VdbeSorterReset(Vdbe *p){
sqlite3VdbeMemRelease(&pSorter->data);
sqliteFree(pSorter);
}
p->pSortTail = 0;
}
/*
@@ -1604,7 +1605,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem){
}
if( flags&MEM_Int ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00010000)<<32)-1)
# define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
i64 i = pMem->i;
u64 u = i<0 ? -i : i;
if( u<=127 ) return 1;

View File

@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.4 2005-04-05 04:15:01 tabuleiro Exp $
** $Id: where.c,v 1.5 2005-04-29 04:26:04 tabuleiro Exp $
*/
#include "sqliteInt.h"
@@ -599,8 +599,7 @@ WhereInfo *sqlite3WhereBegin(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
Fetch *pFetch /* Initial location of cursors. NULL otherwise */
ExprList **ppOrderBy /* An ORDER BY clause, or NULL */
){
int i; /* Loop counter */
WhereInfo *pWInfo; /* Will become the return value of this function */

View File

@@ -8,6 +8,7 @@
#include <qmessagebox.h>
//utility functions
/*
uint utf16len(const ushort* utf16)
{
uint len=0;
@@ -21,7 +22,7 @@ QString StringFromUTF16(const void* utf16)
QString result;
result.setUnicodeCodes(static_cast<const ushort*>(utf16), utf16len(static_cast<const ushort*>(utf16)));
return result;
}
}*/
void DBBrowserTable::addField(int order, const QString& wfield,const QString& wtype)
@@ -85,9 +86,9 @@ bool DBBrowserDB::open ( const QString & db)
lastErrorMessage = QString("no error");
err = sqlite3_open16(db.ucs2(), &_db);
err = sqlite3_open(db.utf8(), &_db);
if ( err ) {
lastErrorMessage = StringFromUTF16(sqlite3_errmsg16(_db));
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
sqlite3_close(_db);
_db = 0;
return false;
@@ -114,7 +115,7 @@ bool DBBrowserDB::setRestorePoint()
if (_db){
if ( SQLITE_OK != sqlite3_exec(_db,"BEGIN TRANSACTION RESTOREPOINT;",
NULL,NULL,NULL) ) {
lastErrorMessage = StringFromUTF16(sqlite3_errmsg16(_db));
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
return false;
}
setDirty(false);
@@ -129,7 +130,7 @@ bool DBBrowserDB::save()
if (_db){
if ( SQLITE_OK != sqlite3_exec(_db,"COMMIT TRANSACTION RESTOREPOINT;",
NULL,NULL,NULL) ) {
lastErrorMessage = StringFromUTF16(sqlite3_errmsg16(_db));
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
return false;
}
setDirty(false);
@@ -144,7 +145,7 @@ bool DBBrowserDB::revert()
if (_db){
if ( SQLITE_OK != sqlite3_exec(_db,"ROLLBACK TRANSACTION RESTOREPOINT;",
NULL,NULL,NULL) ) {
lastErrorMessage = StringFromUTF16(sqlite3_errmsg16(_db));
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
return false;
}
setDirty(false);
@@ -160,8 +161,8 @@ bool DBBrowserDB::create ( const QString & db)
lastErrorMessage = QString("no error");
if( sqlite3_open16(db.ucs2(), &_db) != SQLITE_OK ){
lastErrorMessage = StringFromUTF16(sqlite3_errmsg16(_db));
if( sqlite3_open(db.utf8(), &_db) != SQLITE_OK ){
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
sqlite3_close(_db);
_db = 0;
return false;
@@ -329,17 +330,6 @@ bool DBBrowserDB::addRecord ( )
if (SQLITE_OK==sqlite3_exec(_db,statement.utf8(),NULL,NULL, &errmsg)){
ok=true;
int newrowid = sqlite3_last_insert_rowid(_db);
//append to recordlist
QStringList newRec;
QString strowid;
strowid.setNum(newrowid);
newRec << strowid;
for (uint a=0; a< browseFields.count();a++){
newRec << "";
}
browseRecs.append(newRec);
//insert rowid into idmap, mapping to record in browseFields (0 based)
idmap.insert(newrowid,browseRecs.count()-1);
} else {
lastErrorMessage = QString(errmsg);
}
@@ -383,47 +373,52 @@ bool DBBrowserDB::updateRecord(int wrow, int wcol, const QString & wtext)
char * errmsg;
if (!hasValidBrowseSet) return false;
if (!isOpen()) return false;
bool ok = false;
bool ok = true;
lastErrorMessage = QString("no error");
rowList::iterator rt = browseRecs.at(wrow);
QString rowid = (*rt).first();
QStringList::Iterator cv = (*rt).at(wcol+1);//must account for rowid
QStringList::Iterator ct = browseFields.at(wcol);
sqlite3_stmt *vm;
const char *tail;
int ncol;
int err;
QString statement = "UPDATE ";
statement.append(curBrowseTableName.latin1());
statement.append(" SET ");
statement.append(*ct);
statement.append("=");
char * formSQL = sqlite3_mprintf("%Q",static_cast<const char*>(wtext.utf8()));
statement.append(formSQL);
if (formSQL) sqlite3_free(formSQL);
statement.append("=?");
statement.append(" WHERE rowid=");
statement.append(rowid.latin1());
statement.append(";");
logSQL(statement, kLogMsg_App);
setDirty(true);
err=sqlite3_prepare(_db,statement.utf8(),-1,
&vm, &tail);
if (err == SQLITE_OK){
err = sqlite3_bind_text(vm, 1, wtext.utf8(), -1, SQLITE_TRANSIENT);
if (err == SQLITE_OK){
while ( sqlite3_step(vm) == SQLITE_ROW ){
ncol = sqlite3_data_count(vm);
}
sqlite3_finalize(vm);
} else{
ok = false;
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
}
}else{
ok = false;
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
}
(*cv) = wtext;
if (_db){
logSQL(statement, kLogMsg_App);
setDirty(true);
if (SQLITE_OK==sqlite3_exec(_db,statement.utf8(),
NULL,NULL,&errmsg)){
ok=true;
/*update local copy*/
(*cv) = wtext.latin1();
} else {
lastErrorMessage = QString(errmsg);
}
}
/*rowIdMap::iterator mit = idmap.find(rowid.toInt());
qDebug("column with rowid %s is %d",rowid.latin1(),*mit);*/
return ok;
}
@@ -449,7 +444,7 @@ bool DBBrowserDB::browseTable( const QString & tablename )
void DBBrowserDB::getTableRecords( const QString & tablename )
{
sqlite3_stmt *vm;
const void *tail;
const char *tail;
int ncol;
QStringList r;
@@ -465,7 +460,7 @@ void DBBrowserDB::getTableRecords( const QString & tablename )
statement.append(" ORDER BY rowid; ");
//qDebug(statement);
logSQL(statement, kLogMsg_App);
err=sqlite3_prepare16(_db,statement.ucs2(),statement.length(),
err=sqlite3_prepare(_db,statement.utf8(),-1,
&vm, &tail);
if (err == SQLITE_OK){
int rownum = 0;
@@ -473,7 +468,7 @@ void DBBrowserDB::getTableRecords( const QString & tablename )
r.clear();
ncol = sqlite3_data_count(vm);
for (int e=0; e<ncol; e++){
QString rv(StringFromUTF16(sqlite3_column_text16(vm, e)));
QString rv(QString::fromUtf8((const char *) sqlite3_column_text(vm, e)));
r << rv;
if (e==0){
idmap.insert(rv.toInt(),rownum);
@@ -489,28 +484,71 @@ void DBBrowserDB::getTableRecords( const QString & tablename )
}
}
resultMap DBBrowserDB::getFindResults( const QString & wstatement)
resultMap DBBrowserDB::getFindResults( const QString & wfield, const QString & woperator, const QString & wsearchterm)
{
//we may need to modify woperator and wsearchterm, so use copies
QString * finaloperator = new QString(woperator);
QString * finalsearchterm = new QString(wsearchterm);
//special case for CONTAINS operator: use LIKE and surround the search word with % characters
if (woperator.compare("contains")==0){
finaloperator = new QString("LIKE");
QString newsearchterm = "%";
newsearchterm.append(wsearchterm);
newsearchterm.append("%");
finalsearchterm = new QString( newsearchterm);
}
QString statement = "SELECT rowid, ";
statement.append(wfield);
statement.append(" FROM ");
statement.append( curBrowseTableName);
statement.append(" WHERE ");
statement.append(wfield);
statement.append(" ");
statement.append(*finaloperator);
statement.append(" ");
statement.append(" ? ORDER BY rowid; ");
//searchterm needs to be quoted if it is not a number
bool isnumber = false;
wsearchterm.toDouble(&isnumber );
if (!isnumber ) wsearchterm.toInt(&isnumber , 10);
sqlite3_stmt *vm;
const void *tail;
const char *tail;
int ncol;
int rownum = 0;
int recnum = 0;
QString r;
int err=0;
resultMap res;
lastErrorMessage = QString("no error");
logSQL(wstatement, kLogMsg_App);
err=sqlite3_prepare16(_db,wstatement.ucs2(),wstatement.length(),
logSQL(statement, kLogMsg_App);
err=sqlite3_prepare(_db,statement.utf8(),-1,
&vm, &tail);
if (err == SQLITE_OK){
int rownum = 0;
int recnum = 0;
QString r;
if (!isnumber ) {//not a number, quote it
sqlite3_bind_text(vm, 1, (*finalsearchterm).utf8(), -1, SQLITE_TRANSIENT);
} else {//append the number, unquoted
double db = wsearchterm.toDouble(&isnumber );
if (isnumber)
{
sqlite3_bind_double(vm, 1, db);
}else {
int inte = wsearchterm.toInt(&isnumber, 10);
if (isnumber)
{
sqlite3_bind_int(vm, 1, inte);
}
}
}
while ( sqlite3_step(vm) == SQLITE_ROW ){
ncol = sqlite3_data_count(vm);
for (int e=0; e<ncol; e++){
r = StringFromUTF16(sqlite3_column_text16(vm, e));
r = QString::fromUtf8((const char *) sqlite3_column_text(vm, e));
if (e==0){
rownum = r.toInt();
rowIdMap::iterator mit = idmap.find(rownum);
@@ -519,10 +557,10 @@ resultMap DBBrowserDB::getFindResults( const QString & wstatement)
}
res.insert(recnum, r);
}
sqlite3_finalize(vm);
}else{
lastErrorMessage = StringFromUTF16(sqlite3_errmsg16(_db));
}else{
lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db));
}
return res;
}
@@ -617,7 +655,7 @@ void DBBrowserDB::updateSchema( )
{
// qDebug ("Getting list of tables");
sqlite3_stmt *vm;
const void *tail;
const char *tail;
int ncol;
QStringList r;
int err=0;
@@ -633,16 +671,15 @@ void DBBrowserDB::updateSchema( )
"FROM sqlite_master "
"WHERE type='table' ;";
err=sqlite3_prepare16(_db,statement.ucs2(),statement.length()
/*"ORDER BY name;"*/ ,
err=sqlite3_prepare(_db, (const char *) statement.latin1(),-1,
&vm, &tail);
if (err == SQLITE_OK){
logSQL(statement, kLogMsg_App);
while ( sqlite3_step(vm) == SQLITE_ROW ){
num.setNum(tabnum);
QString val1, val2;
val1 = StringFromUTF16(sqlite3_column_text16(vm, 0));
val2 = StringFromUTF16(sqlite3_column_text16(vm, 1));
val1 = QString((const char *) sqlite3_column_text(vm, 0));
val2 = QString((const char *) sqlite3_column_text(vm, 1));
tbmap[num] = DBBrowserTable(val1, val2);
tabnum++;
}
@@ -654,24 +691,31 @@ void DBBrowserDB::updateSchema( )
//now get the field list for each table in tbmap
tableMap::Iterator it;
for ( it = tbmap.begin(); it != tbmap.end(); ++it ) {
statement = "SELECT * FROM ";
statement = "PRAGMA TABLE_INFO(";
statement.append( (const char *) it.data().getname().latin1());
statement.append(" LIMIT 1;");
statement.append(");");
logSQL(statement, kLogMsg_App);
err=sqlite3_prepare16(_db,statement.ucs2(),statement.length(),
err=sqlite3_prepare(_db,statement.utf8(),-1,
&vm, &tail);
if (err == SQLITE_OK){
err = sqlite3_step(vm);
if ((err==SQLITE_ROW)||(err==SQLITE_DONE)){
ncol = sqlite3_column_count(vm);
it.data(). fldmap.clear();
for (int e=0; e<ncol; e++) {
it.data().addField(e,StringFromUTF16(sqlite3_column_name16(vm, e)),StringFromUTF16(sqlite3_column_decltype16(vm, e)));
}
}
sqlite3_finalize(vm);
}else{
it.data(). fldmap.clear();
int e = 0;
while ( sqlite3_step(vm) == SQLITE_ROW ){
if (sqlite3_column_count(vm)==6) {
QString val1, val2;
int ispk= 0;
val1 = QString((const char *) sqlite3_column_text(vm, 1));
val2 = QString((const char *) sqlite3_column_text(vm, 2));
ispk = sqlite3_column_int(vm, 5);
if (ispk==1){
val2.append(QString(" PRIMARY KEY"));
}
it.data().addField(e,val1,val2);
e++;
}
}
sqlite3_finalize(vm);
} else{
lastErrorMessage = QString ("could not get types");
}
}
@@ -680,14 +724,14 @@ void DBBrowserDB::updateSchema( )
"WHERE type='index' ";
/*"ORDER BY name;"*/
//finally get indices
err=sqlite3_prepare16(_db,statement.ucs2(),statement.length(),
err=sqlite3_prepare(_db,statement.utf8(),-1,
&vm, &tail);
logSQL(statement, kLogMsg_App);
if (err == SQLITE_OK){
while ( sqlite3_step(vm) == SQLITE_ROW ){
QString val1, val2;
val1 = StringFromUTF16(sqlite3_column_text16(vm, 0));
val2 = StringFromUTF16(sqlite3_column_text16(vm, 1));
val1 = QString((const char *) sqlite3_column_text(vm, 0));
val2 = QString((const char *) sqlite3_column_text(vm, 1));
num.setNum(idxnum);
idxmap[num] = DBBrowserIndex(val1,val2);
idxnum ++;

View File

@@ -17,8 +17,8 @@
enum
{
kLogMsg_User,
kLogMsg_App
kLogMsg_User,
kLogMsg_App
};
static QString applicationName = QString("SQLite Database Browser");
@@ -35,8 +35,9 @@ typedef QValueList<QStringList> rowList;
typedef QMap<int, QString> resultMap;
//utility functions
/*
uint utf16len(const ushort* utf16);
QString StringFromUTF16(const void* utf16);
QString StringFromUTF16(const void* utf16);*/
class DBBrowserField
{
@@ -47,7 +48,7 @@ class DBBrowserField
{ }
QString getname() const { return name; }
QString gettype() const { return type; }
private:
private:
QString name;
QString type;
};
@@ -89,36 +90,36 @@ private:
class DBBrowserDB
{
public:
DBBrowserDB (): _db( 0 ) , hasValidBrowseSet(false) {}
~DBBrowserDB (){}
bool open ( const QString & db);
bool create ( const QString & db);
void close ();
bool compact ();
bool setRestorePoint();
bool save ();
bool revert ();
bool dump( const QString & filename);
bool reload( const QString & filename, int * lineErr);
bool executeSQL ( const QString & statement);
bool executeSQLDirect ( const QString & statement);
void updateSchema() ;
bool addRecord();
bool deleteRecord(int wrow);
bool updateRecord(int wrow, int wcol, const QString & wtext);
bool browseTable( const QString & tablename );
QStringList getTableFields(const QString & tablename);
QStringList getTableTypes(const QString & tablename);
QStringList getTableNames();
QStringList getIndexNames();
resultMap getFindResults( const QString & wstatement);
int getRecordCount();
bool isOpen();
void setDirty(bool dirtyval);
void setDirtyDirect(bool dirtyval);
bool getDirty();
void logSQL(QString statement, int msgtype);
sqlite3 * _db;
DBBrowserDB (): _db( 0 ) , hasValidBrowseSet(false) {}
~DBBrowserDB (){}
bool open ( const QString & db);
bool create ( const QString & db);
void close ();
bool compact ();
bool setRestorePoint();
bool save ();
bool revert ();
bool dump( const QString & filename);
bool reload( const QString & filename, int * lineErr);
bool executeSQL ( const QString & statement);
bool executeSQLDirect ( const QString & statement);
void updateSchema() ;
bool addRecord();
bool deleteRecord(int wrow);
bool updateRecord(int wrow, int wcol, const QString & wtext);
bool browseTable( const QString & tablename );
QStringList getTableFields(const QString & tablename);
QStringList getTableTypes(const QString & tablename);
QStringList getTableNames();
QStringList getIndexNames();
resultMap getFindResults( const QString & wfield, const QString & woperator, const QString & wsearchterm);
int getRecordCount();
bool isOpen();
void setDirty(bool dirtyval);
void setDirtyDirect(bool dirtyval);
bool getDirty();
void logSQL(QString statement, int msgtype);
sqlite3 * _db;
QStringList decodeCSV(const QString & csvfilename, char sep, char quote, int maxrecords, int * numfields);