mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-20 19:11:39 -06:00
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:
@@ -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.
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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:
|
||||
**
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
**
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 ++;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user