QT QSqlDatabase open() function fails for long database name(database filepath) - qt

QSqlError(-1, "Error opening database", "unable to open database file") when we try to open a qsqldatabase which having long database name(not supported more than 256 bytes)
I tried to remove directory path from database file name and change the current working directory by the above said directory, now file name is small but open call still failed
QString dbName = "/home/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789/abc123456789test.db"
QFileInfo fi(dbName);
QDir d = fi.dir();
char buffer[4096];
char* cwd = getcwd(buffer, 4096);
chdir(d.canonicalPath().toStdString().c_str());
m_sqldb = QSqlDatabase::addDatabase("QSQLITE",connectionName)
m_sqldb.setDatabaseName(fi.fileName());
if(!m_sqldb.isOpen()) {
ok = m_sqldb.open();
if (ok) {
//////
}
else {
qDebug()<<dbName<<m_sqldb.lastError();
}
}

Related

QNetworkAccessManager uploads fail

In the app I upload a video file (24Mb about) every 2 minutes and this works well. It works also if I upload a new file after the previous one have ended.
Two minutes is enough time for the file to upload, but if the connection is slow and a new file tries to upload the app hungs.
Can I somehow have two uploads at the same time?
My code:
QString MainWindow::rename_video()
{
QString oldName="C:/Qt/Qt5.10.1/Nuevo/build_principal_16/riderout.mp4";
QString newName=QString::number(QDateTime::currentMSecsSinceEpoch())+".mp4";
QFile f(oldName);
if (f.rename(newName)) {
// upload
m_file = new QFile("C:/Qt/Qt5.10.1/Nuevo/build_principal_16/"+newName);
QFileInfo fileInfo(*m_file);
QUrl url("ftp://jumpemirates.com/app/history/"+newName);
url.setUserName("user#email.com");
url.setPassword("password");
url.setPort(21);
if (m_file->open(QIODevice::ReadOnly))
QNetworkReply *reply = m_manager->put(QNetworkRequest(url), m_file);
} else {
qWarning("Unable to rename video file.");
return "";
}
return newName;
}
void MainWindow::uploadFinished(QNetworkReply *reply) {
if (!reply->error()) {
m_file->close();
m_file->deleteLater();
reply->deleteLater();
}
}

program crashes when trying to access clipboard

I am trying to get clipboard data via QClipboard. Here is my code:
void MainWindow::getText()
{
QClipboard *clipboard = QGuiApplication::clipboard();
const QMimeData *mime = clipboard->mimeData (QClipboard::Selection);
QString originalText = clipboard->text(); // no crashes in windows
//QString originalText = mime->text (); //this line causing program crash
.................
}
getText() called every 5 second using QTimer. The above code works perfectly in linux, when I try to run the code in windows 7 it crashed.
clipboard->mimeData can be null, so you might want to either cache the previous state, or do the following:
QString originalText = mime ? mime->text() : QString();
Windows doesn't support QClipboard::Selection, that's why application crashes everytime. Here is how I solved it
QString originalText;
if(QSysInfo::productType() == "windows") {
QString clipboard = QApplication::clipboard()->text();
originalText = clipboard;
} else {
// for linux
QClipboard *clipboard = QGuiApplication::clipboard();
const QMimeData *mime = clipboard->mimeData (QClipboard::Selection);
originalText = mime->text ();
}

How can I read a folder owned by root with Vala?

I'm trying to read the path /var/cache/apt/archives with the following permissions:
drwxr-xr-x 3 root root 90112 ago 2 14:36 archives
And I got the following error:
ERROR: Error opening directory '/var/cache/apt/archives/partial': Permission denied
Can somebody give me a hand with this?
The source code is the following:
using Gtk;
using GLib;
private int64[] get_folder_data (File file, string space = "", Cancellable? cancellable = null) throws Error
{
FileEnumerator enumerator = file.enumerate_children (
"standard::*",
FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable);
int64 files = 0;
int64 size = 0;
int64[] data = new int64[2];
FileInfo info = null;
while (cancellable.is_cancelled () == false && ((info = enumerator.next_file (cancellable)) != null)) {
if (info.get_file_type () == FileType.DIRECTORY) {
File subdir = file.resolve_relative_path (info.get_name ());
get_folder_data (subdir, space + " ", cancellable);
} else {
files += 1;//Sum Files
size += info.get_size ();//Accumulates Size
}
}
if (cancellable.is_cancelled ()) {
throw new IOError.CANCELLED ("Operation was cancelled");
}
data[0] = files;
data[1] = size;
stdout.printf ("APT CACHE SIZE: %s\n", files.to_string());
stdout.printf ("APT CACHE FILES: %s\n", size.to_string());
return data;
}
public static int main (string[] args) {
Gtk.init (ref args);
File APT_CACHE_PATH = File.new_for_path ("/var/cache/apt/archives");
try {
get_folder_data (APT_CACHE_PATH, "", new Cancellable ());
} catch (Error e) {
stdout.printf ("ERROR: %s\n", e.message);
}
Gtk.main ();
return 0;
}
And the command I used for compile is the following:
valac --pkg gtk+-3.0 --pkg glib-2.0 --pkg gio-2.0 apt-cache.vala
If you run your app as a normal user, you have to exclude the "partial" dir, it has more restrictive permissions (0700):
drwx------ 2 _apt root 4096 Jul 29 11:36 /var/cache/apt/archives/partial
One way to exclude the partial dir is to just ignore any dir that is inaccessible:
int64[] data = new int64[2];
FileEnumerator enumerator = null;
try {
enumerator = file.enumerate_children (
"standard::*",
FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable);
}
catch (IOError e) {
stderr.printf ("WARNING: Unable to get size of dir '%s': %s\n", file.get_path (), e.message);
data[0] = 0;
data[1] = 0;
return data;
}
In addition it might be a good idea to always explicitly ignore the partial folder.
If you are planning to make your utility useful for the root user as well, you might even think of adding a command line option like "--include-partial-dir".
Also the same thing can be done with simple bash commands which is much easier than writing your own program.
du -sh /var/cache/apt/archives
find /var/cache/apt/archives -type f | wc -l
Note that du and find also warn about the inaccessible partial dir:
$ du -sh /var/cache/apt/archives
du: cannot read directory '/var/cache/apt/archives/partial': Permission denied
4.6G /var/cache/apt/archives
$ find /var/cache/apt/archives -type f | wc -l
find: '/var/cache/apt/archives/partial': Permission denied
3732

How to use QFileDialog::getsaveFileName to save a ui file with QFormBuilder?

What I want:
When I call save(), I would like to use the QFileDialog to get the file, and save ui file with QFormBuilder(because it lets me save ui files recognizable by Qdesigner)
What I have:
I have a method called save()
void MainWindow::save()
{
QString savef = QFileDialog::getSaveFileName(this, tr("Save"), "file", tr("UI files (*.ui)"));
//here down I would like to use the savef to save ui file
QFormbuilder builder;
builder.save(savef, myui);
}
But savef is not QIODevice, and the Qt is complaining about it.
Any idea how I can do it?
Thanks.
You need to create a QFile and pass that to save():
QFile out(savef);
if (!out.open(QIODevice::WriteOnly)) {
const QString error = tr("Could not open %1 for writing: %2").arg(savef, out.errorString());
//report the error in some way...
return;
}
builder.save(&out, myui);
const bool flushed = out.flush();
if (!flushed || out.error() != QFile::NoError) { // QFormBuilder lacks proper error reporting...
const QString error = tr("Could not write form to %1: %2").arg(savef, out.errorString());
//report error
}
When using Qt 5.1 or newer, I'd use QSaveFile instead:
QSaveFile out(savef);
if (!out.open(QIODevice::WriteOnly)) {
const QString error = tr("Could not open %1 for writing: %2").arg(savef, out.errorString());
//report the error in some way...
return;
}
builder.save(&out, myui);
if (!out.commit()) {
//report error
}

MethodAccessException when updating a record in sqlite db

I encounter this exception when I try to updating a record with following statement.
UPDATE GroupTable SET groupId=100 WHERE groupId=101
I tested the statement under SQLite Manager of Firefox plug-in, and it works.
The error message is as following image. It crashed at the os_win_c.cs, the method named getTempname().
Well, I modified the original codes and fixed this bug.
The Path.GetTempPath() doesn't work because the sandbox enviroment. It has no access right.
I fixed by following codes. And it works now.
static int getTempname(int nBuf, StringBuilder zBuf)
{
const string zChars = "abcdefghijklmnopqrstuvwxyz0123456789";
StringBuilder zRandom = new StringBuilder(20);
i64 iRandom = 0;
for (int i = 0; i < 20; i++)
{
sqlite3_randomness(1, ref iRandom);
zRandom.Append((char)zChars[(int)(iRandom % (zChars.Length - 1))]);
}
//! Modified by Toro, 2011,05,10
string tmpDir = "tmpDir";
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
store.CreateDirectory(tmpDir);
//zBuf.Append(Path.GetTempPath() + SQLITE_TEMP_FILE_PREFIX + zRandom.ToString());
zBuf.Append(tmpDir + "/" + SQLITE_TEMP_FILE_PREFIX + zRandom.ToString());
return SQLITE_OK;
}
The above patch will result in an extra folder tmpDir in the isolatedstorage, and the temp files won't be deleted automatically, so it needs to be delete by self. I tried to delete those files in tmpDir in the method of winClose inside os_win_c.cs, and I found it will result in crash when I do VACUUM. Finally, I delete those tmp files when I closed the database. The following is a Dispose method in SQLiteConnection class.
public void Dispose()
{
if (_open)
{
// Original codes for close sqlite database
Sqlite3.sqlite3_close(_db);
_db = null;
_open = false;
// Clear tmp files in tmpDir, added by Toro 2011,05,13
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string tmpDir = "tmpDir";
if (store.DirectoryExists(tmpDir) == false) return;
string searchPath = System.IO.Path.Combine(tmpDir, "*.*");
foreach (string file in store.GetFileNames(searchPath)) {
store.DeleteFile(System.IO.Path.Combine(tmpDir, file));
}
}
}

Resources