insert unicode string in SQLite database from qt - qt

I am creating a SQLite database from qt like this:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", mConnectionName);
db.setDatabaseName("myDattabse.DB");
if (!db.open()) {
return false;
}
When trying to insert Macedonian characters in the SQLite database, the characters are inserted as ???.
According to this link http://www.qtcentre.org/threads/26202-SQLite-connection-and-encoding?highlight=unicode+and+sqllite , I need to create my database with utf-16 encoding to solve my problem. SQLite default encoding is utf-8. How can I do that? Where to specify this option in my code?

From my understanding you should be fine with UTF8, pls, check if an example below would work for you:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if( !db.open() )
{
qDebug() << db.lastError();
qFatal( "Failed to connect." );
}
QSqlQuery query;
query.prepare("CREATE TABLE IF NOT EXISTS names (id INTEGER UNIQUE PRIMARY KEY, test_field VARCHAR(30))");
query.exec();
query.prepare(QObject::trUtf8("INSERT INTO names (id, test_field) VALUES (1, 'тест1')"));
query.exec();
query.prepare(QObject::trUtf8("INSERT INTO names (id, test_field) VALUES (2, 'тест2')"));
query.exec();
QSqlQuery select("SELECT test_field FROM names");
while (select.next())
{
qDebug() << select.value(0).toString();
}
output should be:
"тест1"
"тест2"
now back to your original question, I believe you can have you sqlite database in UTF-16 as default encoding if the database is opened with sqlite3_open16 function. According to QT source code (qsql_sqlite.cpp QSQLiteDriver) they are using sqlite3_open_v2 function to open the connection to database which is UTF-8, but again, there is nothing wrong with it for working correctly with Cyrillic characters.
hope this helps, regards

Related

Use SqlCipher on Visual Studio

I´ve already compiled SQLCipher for windows and encrypt/decrypt a database file using SQLCipher at command line. The problem is at the last part of this tutorial when I use SQLCipher in Visual Studio.
It looks like the application skips this code line, because it is not encrypting neither decrypting, i'm not getting any error.
if (sqlite3_exec(db, (const char*)"PRAGMA key ='password'", NULL, NULL, NULL) == SQLITE_OK){
printf("Accepted Key\n");
};
Can anyone tell me what's wrong? or provide some sample C code?
Thanks in advance.
There are a couple of items to address here. First, checking for SQLITE_OK as a status code from sqlite3_exec does not mean that the provided password is valid for the database. In order to validate that, once the database has been keyed, we recommend you perform a query such as:
SELECT count(*) FROM sqlite_master;
This table will always be present, regardless of the state of your application schema.
Next, to verify that you have properly integrated the SQLCipher library within your application, we can query the database for the PRAGMA cipher_version; reported by the library. Below is a sample for doing so:
int rc;
sqlite3 *db;
sqlite3_stmt *stmt;
rc = sqlite3_open(":memory:", &db);
if(rc != SQLITE_OK){
printf("failed to open database\n");
}
rc = sqlite3_prepare(db, "PRAGMA cipher_version;", -1, &stmt, NULL);
rc = sqlite3_step(stmt);
if(rc == SQLITE_ROW){
printf("SQLCipher version:%s\n", sqlite3_column_text(stmt, 0));
}
sqlite3_finalize(stmt);
if(db != NULL){
sqlite3_close(db);
}

Qt5 use Sqlite Database Select sum()

when I try to select with QSqlQuery:
select mwst, sum(in), sum(out) from costs group by mwst
I got the error: QSqlQuery::value: not positioned on a valid record
In SQLite Database Browser tool the select runs without error.
Thanks for help!
have you used bool QSqlQuery::next() to set the query on a valid value (if the query succeeded, you should get results
like:
QSqlQuery qry("select * from table");
while (qry.next())
{
qDebug() << qry.value(0).toString();
}

qt sqlite insert into autoincrement table yields two rows

Hi
I have a sqlite db which I am manipulating using qts built in sqlite database driver.
I have a small test app that allows me to run an sql query from a line edit and it will be executed and the results are then updated in a view of the relevant model.
I have created a table which uses autoincremented primary key values, but if I execute an insert statement without providing the key, I get two rows inserted, each with an autoincremented value.
If I provide the key value, only one row is created. Any ideas why this is?
Table is simple enough, e.g
CREATE TABLE GroupNames ( ID integer PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, Name varchar(50))
and when I run the query
insert into groupnames (name) values ("testName");
I get two new rows with autoincremented ids. However, if I run
insert into groupnames (id, name) values (100, "testName");
I get one row as expected, with the correct id 100.
Also of note is that if I try
insert into table groupnames (id, name) values (100, "testName");
insert into table groupnames (name) values ("testName");
the query does not run.
The qt code to run the query could not be simpler:
QSqlQuery *DbCore::run_query(const QString &query_string)
{
QSqlDatabase db = QSqlDatabase::database(defConnectionName);
if(!db.isOpen())
return NULL;
QSqlQuery *q = new QSqlQuery(query_string, db);
q->exec();
return q;
}
I have added some logging code to check that the query is executed once:
QSqlDatabase db = QSqlDatabase::database(defConnectionName);
if(!db.isOpen())
return NULL;
qDebug() << "Running query:" << query_string;
QSqlQuery *q = new QSqlQuery(query_string, db);
if(!q->exec())
qDebug() << "Error running query:" << q->lastError();
return q;
The log confirms that I'm only executing once:
Running query: "insert into groupnames (name) values ("hello")"
If i then check the database using sqlite3 shell (to remove any doubt about qt views etc):
sqlite> select * from groupnames;
1|hello
2|hello
question was answered above in a comment:
As i see in the documentation, when you create a QSqlQuery the way you do, the query, if not empty, is executed. To create the QSqlQuery and execute the query, use this: QSqlQuery *q = new QSqlQuery(db); q->exec(query_string) To see the last executed query, use QSqlQuery::lastQuery() And for the last query that was successfully executed QSqlQuery::executedQuery() Hope this helps. – Hector Mar 16 at

Delete All Data with SQLite delete syntax?

I've made a button that removes all the objects in my array, which is shown in my tableView. Then it reloads data and the tableview is empty. But how can I delete all the data from my SQLite database as well, and not just the array? Now the data occurs when I restart. I have tried this:
Button void:
- (void) deleteAllButton_Clicked:(id)sender {
[appDelegate removeAllBooks:nil];
[self.tableView reloadData];
}
Appdelegate void:
-(void) removeAllBooks:(Book *)bookObj {
//Delete it from the database.
[bookObj deleteAllBooks];
//Remove it from the array.
[bookArray removeAllObjects];
}
Delete syntax in Book.m
- (void) deleteAllBooks {
if(deleteStmt == nil) {
const char *sql = "WHAT DO I HAVE TO DO TO DELETE ALL THE ROWS?";
if(sqlite3_prepare_v2(database, sql, -1, &deleteStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating delete statement. '%s'", sqlite3_errmsg(database));
}
//When binding parameters, index starts from 1 and not zero.
sqlite3_bind_int(deleteStmt, 1, bookID);
if (SQLITE_DONE != sqlite3_step(deleteStmt))
NSAssert1(0, #"Error while deleting. '%s'", sqlite3_errmsg(database));
sqlite3_reset(deleteStmt);
}
Well, the normal SQL syntax would be:
DELETE FROM tablename
If you have a standard primary id column (and you should) you can do
DELETE FROM tablename WHERE id > -1;
And this will delete all rows in the table since there is no id less than 0.
DELETE FROM tablename did not work for me. I was using a sqlite3 database on iPhone, which I assume the poster was, as well. For me to get this to work, I needed to:
DROP table tablename
followed by a CREATE statement, if I wanted the table to still exist (without any rows).
Of course, that requires knowing the right CREATE statement. Using the SQLManager plugin for Firefox quickly reverse-engineered for me the correct CREATE statement to use. I never figured out why DELETE FROM tablename didn't work, but it definitely didn't, in my case.

Is there a more expressive way of executing SQL query using Qt?

I currently have this code:
// Construct query
QString const statement = QString("drop database if exists %1")
.arg(databaseName_);
QSqlQuery query(db);
query.exec(statement);
Is there a better way to code than the above?
Specifically, I dont like how I use QString for SQL statement. It'd be nice if Qt has some class so that I could do something like:
// Construct query
QSomeClass statement = "drop database if exists %1";
statement.setArg(1, databaseName_); // Replace all %1 in the original string.
QSqlQuery query(db);
query.exec(statement);
I think you are basically describing query placeholders:
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
query.exec();
The only difference between the code snipped above and QSomeClass you described is the fact that you have to specify database when creating the query.

Resources