Qt - sync SQLite data base on application close - qt

Data base is oppened in application by following code:
db = QSqlDatabase::addDatabase("QSQLITE");
bool dbExists = QFile::exists("base.db");
db.setDatabaseName("base.db"); // ":memory:"
if (!db.open()) {
db.close();
QMessageBox::critical(0, tr("Cannot open database"),
tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it."), QMessageBox::Cancel);
return;
}
if (!dbExists)
createDB();
I've mapped some tables to widgets via QDataWidgetMapper. All work fine during application run. Changes take effect. But all the chages are lost after restarting application with existing base.db. Application starts much faster, so it opens this file but with unchanged data base.
I've tried to close application by
db.close();
this->close();
There is no luck. Even the sync query did not help after db.open:
QSqlQuery query(db);
query.exec("PRAGMA synchronous = ON;");
What have I missed to sync changes to base.db?
UPDATE. You can try to build sqlwidgetmapper standard example and change :memory: to "base.db" file. It doesn't save changed data to file too.

Problem is possibly manual submit policy.
Either switch that to auto, or manually call QDataWidgetMapper::submit() at appropriate time (before new value is lost from the widget).

Related

How to solve room data integrity error due to identityHash mismatch?

Issue:
Whenever I make changes to the database or the model, I get the following Room data integrity error:
My understanding is that I shouldn't need to increase the version number since I am using .fallbackToDestructiveMigration().
Background:
I using DB Browser for SQLite (v3.12.0) to make changes to the database.
I frequently make changes to my app/database, which is still in development. So, I am using a .fallbackToDestructiveMigration() (see codelab example).
File: RoomDB.java
#Database(entities =
{Note.class, Label.class, Join_ScheduleLabel.class, Schedule.class},
version = 1)
#TypeConverters(DataConverters.class)
public abstract class RoomDB extends androidx.room.RoomDatabase {
public static final String DATABASE_NAME = "vk_prepop.sqlite";
private static RoomDB INSTANCE;
public static RoomDB getInstance(final Context context) {
if (INSTANCE == null) {
synchronized (RoomDB.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.getApplicationContext(),
RoomDB.class,
DATABASE_NAME)
// Source: https://developer.android.com/training/data-storage/room/prepopulate
.createFromAsset(DATABASE_NAME)
// Todo: Remove Destructive Migration
// Wipes and rebuilds instead of migrating if no Migration object.
.fallbackToDestructiveMigration()
.build();
}
}
}
return INSTANCE;
}
public abstract RoomDao getRoomDao();
}
Troubleshooting Steps Taken:
Verifying the entities of the RoomDB.java file match the models and database.
Going into the App Info and tapping "Clear data" (see SO answer).
Uninstalling the app.
Making setting android:allowBackup="false" in the manifest (see SO answer).
Possible Solution:
In live-love's answer he says there may be an identityHash mismatch, but I am not sure how to resolve this using DB Browser for SQLite.
My understanding is that I shouldn't need to increase the version number since I am using .fallbackToDestructiveMigration().
The fallBackToDestructiveMigration only runs if a migration is required and there is no Migration covering the migration.
In your situation the issue is that you have included the room_master_table in the pre-packaged database and hence the identity_hash columns is available for comparison (which would be incorrect if changes were made to the schema that affected how room generates the identity_hash from the schema).
By including the room_master_table you are introducing an unnecessary complexity.
If you omit this table from the pre-packaged database, then it will be created and populated, with the appropriate identity_hash when it is created from the asset (i.e. when the database doesn't exist). As such you then only have to make the appropriate changes to the asset (the pre-packaged database), delete the current database (e.g. uninstall the App or clear the Apps data) and then run the App.
live-love's answer states that there may be an identityHash mismatch. Indeed this was the case. Here is how I resolved the issue using DB Browser for SQLite (v3.12.0).
Step 1: In Android Studio's project panel choose the "Project" view:
Step 2: Then double-click on the json file for your schema:
Step 3: Copy the identityHash in this json file:
Step 4: Open your database in DB Browser for SQLite. Click the "Browse Data" tab. Then from the drop-down menu choose "room_master_table".
Step 5: Compare the identifyHash from the json file in Android Studio to the identityHash in DB Browser for SQLite. If the hashes are different, this can be the cause of you Room data integrity error.
Step 6: So, paste the identityHash from the Android Studio's json file into the identityHash cell in the DB Browser for SQLite.
Step 7: Then press Ctrl+Shift+S to save the database.
Step 8: Click "Close Database".
Step 9: In your app on your phone or emulator go to "App Info" -> "Storage" -> "Clear data".
Step 10: Then in Android Studio press "Run app".
Problem solved... at least for me. If these steps did not help, please review these additional troubleshooting steps.

SQLite data cleanup in Windows 8 application

In my windows 8.1 application i am using SQLitePCL on top of SQLite.
I create the tables and populate my test data on application launch.
I only create DB tables if the tables are not existing through SQL is exists keyword in the queries.
Now how do i clean up the populated test data. Do i have to run delete queries when application shuts down ?.
I am testing through Windows simulator 8. Is there no way to clean up the app data which will flush the db in the simulator ?
cheers,
Saurav
I suggest you to recreate DB schema every time you need to flush populated data. You have at least two options to achieve that:
At first: in the same way as you create DB tables if they are not exist, you can delete DB when the data should be flushed and recreate it. I use this code to open/create DB file.
private async Task<bool> IsDBExistAsync()
{
bool isExist = true;
try
{
StorageFile sf = await ApplicationData.Current.LocalFolder.GetFileAsync(DATABASE_NAME);
}
catch (Exception)
{
isExist = false;
}
return isExist;
}
At second: open explorer window and navigate to C:\Users\{username}\AppData\Local\Packages\{package_family_name}\LocalState and delete DB file manually when it is not needed anymore. "package_family_name" is specified in Package.appxmanifest of your app (Packaging tab).
Bonus item: if you are developing phone part - you can access local storage using Windows Phone Power Tools utility.

Using ffmpeg in asp.net

I needed a audio conversion library. After already pulling my hair..I have given up on the fact that there is no such audio library out there..every library out there has some or the other problem.
The only option left is ffmpeg which is the best but unfortunately you cannot use it in asp.net (not directly I mean). Every user on the website that will convert a file; will launch an exe?; I think I will hit the server memory max soon.
Bottom Line: I will try using ffmpeg.exe and see how many users it can support simultaneously.
I went to the ffmpeg website and in the windows download section I found 3 different version; static, shared and dev.
Does any one know which would be the best? All packed in one exe (static) or dll's separely and exe small, wrt using it in asp.net?
PS: any one has a good library out there..would be great if you can share.
Static builds provide one self-contained .exe file for each program (ffmpeg, ffprobe, ffplay).
Shared builds provide each library as a separate .dll file (avcodec, avdevice, avfilter, etc.), and .exe files that depend on those libraries for each program
Dev packages provide the headers and .lib/.dll.a files required to use the .dll files in other programs.
ffMpeg is the best library out there from what I have used but I wouldn't recommend trying to call it directly from asp.net.
What I have done, is accepted the upload, stored it on the server, or S3 in my case, then have a worker role (if using something like Azure) and a process that continuously looks and monitors for new files to convert.
If you needed a realtime like solution, you could update flags in your database and have an AJAX solution to poll the database to keep providing progress updates, then a link to download once the conversion is complete.
Personally my approach would be
Azure Web Roles
Azure Worker Role
ServiceBus
The WorkerRole starts up and is monitoring the ServiceBus Queue for messages.
The ASP.NET site uploads and stores the file in S3 or Azure
The ASP.NET site then records information in your DB if needed and sends a message to the ServiceBus queue.
The WorkerRole picks this up and converts.
AJAX will be needed on the ASP.NET site if you want a realtime monitoring solution. Otherwise you could send an email when complete if needed.
Using a queuing process also helps you with load as when you are under heavy load people just wait a little longer and it doesn't grind everything to a halt. Also you can scale out your worker roles as needed to balance loads, should it ever become too much for one server.
Here is how I run ffMpeg from C# (you will need to change the parameters for your requirements)
String params = string.Format("-i {0} -s 640x360 {1}", input.Path, "C:\\FilePath\\file.mp4");
RunProcess(params);
private string RunProcess(string Parameters)
{
//create a process info
ProcessStartInfo oInfo = new ProcessStartInfo(this._ffExe, Parameters);
oInfo.UseShellExecute = false;
oInfo.CreateNoWindow = true;
oInfo.RedirectStandardOutput = true;
oInfo.RedirectStandardError = true;
//Create the output and streamreader to get the output
string output = null; StreamReader srOutput = null;
//try the process
try
{
//run the process
Process proc = System.Diagnostics.Process.Start(oInfo);
proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
proc.Close();
proc.Dispose();
}
catch (Exception)
{
// Capture Error
}
finally
{
//now, if we succeeded, close out the streamreader
if (srOutput != null)
{
srOutput.Close();
srOutput.Dispose();
}
}
return output;
}

how to take the backup of sql compact database

I have created a C# windows application with vs2010 and I'm using a SQL Server CE database. I'm looking for a way to backup my database programmatically.
Is there a way to export/import my entire database (as a .sdf file) or just copy it to another location and then import it and replace the current one?Could anyone provide me the code in order to do this?
I'm relatively new to this but I'm guessing this is not something as difficult as it sounds. I couldn't find a clear answer anywhere so any help would be appreciated!
For this task we use the SQL Server Management Objects (SMO) objects that have access to backup/restore functions using asp.net code.
Base on the article How to: Back Up Databases and Transaction Logs here is a part of the sample that make the backup:
// Create the Backup SMO object to manage the execution
Backup backup = new Backup();
// Add the file to backup to
backup.Devices.Add(new BackupDeviceItem(backupPath, DeviceType.File));
// Set the name of the database to backup
backup.Database = databaseName;
// Tell SMO that we are backing up a database
backup.Action = BackupActionType.Database;
backup.Incremental = false;
// Specify that the log must be truncated after the backup is complete.
backup.LogTruncation = BackupTruncateLogType.Truncate;
// Begin execution of the backup
backup.SqlBackup(server);

"String or binary data would be truncated" in uploading file in ASP.NET MVC3

I'm developing some application in ASP.NET MVC3 and trying to upload some file in SQL Server 2008, I have the type varbinary(MAX) in DB and I have the code below for uploading it, but I get the error "String or binary data would be truncated . The statement has been terminated" which I believe it's a data base error, where do you think my problem is? thanks
if (UploadedFile != null)
{
App_MessageAttachment NewAttachment= new App_MessageAttachment { FileName = UploadedFile.FileName, FilteContentType = UploadedFile.ContentType, MessageId = NM.Id, FileData = new byte[UploadedFile.ContentLength] };
UploadedFile.InputStream.Read(NewAttachment.FileData, 0, UploadedFile.ContentLength);
db.App_MessageAttachments.InsertOnSubmit(NewAttachment);
db.SubmitChanges();
}
That is a database error, but it isn't necessarily associated with the file portion of the insert. Check to make sure that FileName, FileContentType, and MessageId are all short enough to fit within their fields in the database.
I would start with Management Studio -> Tools -> SQL Profiler.
Point it at your database and run the upload again. Press pause or stop after you see the error in your app and search for the error message within the trace window. This will give you the SQL that generated this message. If the solution doesn't immediately present itself to you, edit your post with the statement that failed.
Here are some Profiler resources
SQL Server Profiler Step by Step
How To: Use SQL Profiler

Resources