SQLite-PCL : Accessing my own created table? - sqlite

I'm referring to SQLite-PCL tutorial here: https://code.tutsplus.com/tutorials/an-introduction-to-xamarinforms-and-sqlite--cms-23020
I'm very new to SQLite, so I'm lacking in knowledge in lots of basic things - I have tried Googling, can't understand most of it.
Is the call to new SQLiteConnection actually opens up the database or just saying that "the road to the database has been established, whether you access it or not is up to you"?
How do I check if there's already existing database in the devices? And if there is, how do I access it? I have Googled this, but it all seems to be a bit extreme - can't I just call simple OPEN the database?
Is it okay to have multiple SQLiteConnection instances to the same database, if I can be sure that I'm not going to do multiple transaction at the same time?
After I have INSERT into the database, close the app, open up the app back - how do I make sure that there is database created in previous session? Any way to debug this? Because I have no idea if the database is there or not, and I don't know how to access it either..

SQLiteConnection returns a connection object that is used to make subsequent queries
use File.Exists to see if the db file is already present
Yes
Again, use File exists to see if the db file is physically present
Xamarin's ToDo sample provides a good overview of using SQLite with Forms.

Related

QSqlError("5", "Unable to fetch row", "database is locked")

I am getting this error "QSqlError("5", "Unable to fetch row", "database is locked")"
I have done my research and I think the problem arises from the fact that I am executing an INSERT query while the SELECT query is still active, which locks the database. Now I'd imagine people run into this problem often since it is common to write to a database based on the output of a SELECT query, so I wanted to ask what is the best way to solve this? Would I be able to fetch the query (using query.next()) after closing it with query.finish() to unlock the database? Or should I store the result in a temporary container, close the query then iterate over the temporary container?
Thank you very much in advance
Do you have a database reader on when you run this? I had a similar issue that only occurred when I had DB Browser for SQLite running. Make sure that you don't have any other software that has your database file open. I don't always have this issue with using DB Browser for SQLite but when I do, closing the program fixes it.
It addition, I tend to run query.finish() after each query is complete, to ensure no interaction.
I hope this helps you out!

Qt - How to list all existing databases on PostgreSQL server using Qt interface

Could someone please explain how to obtain a list of all existing databases on a PostgreSQL server, to which the user already has access, using Qt? PostgreSQL documentation suggests the following query:
SELECT datname FROM pg_database WHERE datistemplate = false;
What are the correct parameters to the following functions:
QSqlDatabase::setDatabaseName(const QString & name) //"postgres" or "pg_database"?
QSqlDatabase::setUserName(const QString & name) //actual user name?
QSqlDatabase::setPassword(const QString & password) //no password? or user password?
Much appreciated. Thank you in advance.
You appear to have already answered the first part of your question. Connect to the postgres or template1 database and issue the query you've quoted above to get a list of databases. I'm guessing - reading between the lines - that you don't know how to connect to PostgreSQL to send that query, and that's what the second part of your question is about. Right?
If so, the QSqlDatabase accessor functions you've mentioned are used to set connection parameters, so the "correct" values depend on your environment.
If you want to issue the query above - to list databases - then you would probably want to connect to the postgres database as it always exists and isn't generally used for anything specific, it's there just to be connected to. That means you'd call setDatabaseName("postgres");. Passing pg_database to setDatabaseName would be nonsensical, since pg_database is the pg_catalog.pg_database table, it isn't a database you can connect to. pg_database is one of those odd tables that exists in every database, which might be what confused you.
With the other two accessors specify the appropriate username and password for your environment, same as you'd use for psql; there's no possible way I could tell you which ones to use.
Note that if you set a password but one isn't required because authentication is done over unix socket ident, trust, or other non-password scheme the password will be ignored.
If this doesn't cover your question, consider editing it and explaining your problem in more detail. What've you tried? What didn't work how you expected? Error messages? Qt version?

Reporting in ASP.NET

I have an SQL Database and an ASP.NET website built to put data into the database.
One of the project requirements is to build a system that would let the user upload a Crystal Report to the server and run it as needed. This way, the user could create a customized report (for then turning into management, customers) that wouldn't force them to go through a developer.
I'm looking for suggestions on how to accomplish this goal.
Currently, I'm looking for a way to redirect the database connection in the Crystal Report from the database it was developed with to the database it will eventually run on. However, There doesn't seem to be a simple way to do this.
I'm also investigating the ReportViewer object. However, all the code I have seen involves specifying the query for the report in the code, which isn't acceptable.
One option (which I don't like at all) is to let them write their own queries so they can copy the results into Excel. This would mean a blank textbox and information about the structure of the database. Not a good idea for multiple reasons.
Another option is to create one report for each table (and maybe a few extras), let the user copy the data they want into Excel, and go on their merry way.
tl;dr How do I build a flexible reporting system?
=========================================
Continuation: 08/20/2012
I have decided to go the route of b.pell's extension methods. So far, it has gotten me closer than anything else. My code to bind to the CrystalReportViewer is below:
CrystalReportSource rs = new CrystalReportSource();
rs.Report.FileName = Server.MapPath("ReportFiles/") + Request["reportname"];
string connstring = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
rs.ReportDocument.ApplyCredentialsFromConnectionString(connstring);
rs.ReportDocument.ApplyNewDatabaseName("myDBName", "mySchemaName");
rs.ReportDocument.Refresh();
CrystalReportViewer1.ReportSource = rs;
This comes very close to working. It works fine on my dev machine, but when I run the code on the server, it gives the following error:
Logon failed.Error in File CrystalReport2 {5D2E82E5-783E-4DFD-A770-C8AE72A51E4E}.rpt:
Unable to connect: incorrect log on parameters. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Runtime.InteropServices.COMException: Logon failed.Error in File CrystalReport2 {5D2E82E5-783E-4DFD-A770-C8AE72A51E4E}.rpt: Unable to connect: incorrect log on parameters. Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
The error is in this line in the code:
crTable.Location = String.Format("{0}{1}", prefix, crTable.Location.Substring(crTable.Location.LastIndexOf(".") + 1))
When I remove the call to ApplyNewDatabaseName, I am asked to enter the Server Name, the Database name, the Username and the Password or to select Integrated Security. I can't enter the Database Name or the Server Name (those fields are disabled).
Any thoughts?
I think what you're looking for is the Reporting Services, part of Business Intelligence
Or maybe you can setup a UI that let the users pick the tables and columns they need for the report (this way you can limit the information they can access) an write a Dinamic Query Builder Function or something like that.
I answer the changing Crystal Reports connection question a lot (it's something I'd think Crystal would make easier, but I wonder if they don't because that's what their server product does). :D Anyway, you can set the database credentials at runtime. Crystal is very particular in the order it's done, but I have some code that I turned into extension methods that do the trick. This code will go through the main report and all sub reports and change the connection information. This assumes that all sub reports connect to the same database that the main report does (if not, you'll need to modify it to handle multiple connections, but this rarely comes up at least with what I do).
Extension methods to change connection info: http://www.blakepell.com/2012-05-22-crystal-reports-extension-methods
It would be used something like this (although, you're binding to a viewer probably and not exporting, so you could ignore that, this is just for example).
Using rd As New ReportDocument
rd.Load("C:\Temp\CrystalReports\InternalAccountReport.rpt")
rd.ApplyNewServer("serverName or DSN", "databaseUsername", "databasePassword")
rd.ApplyParameters("AccountNumber=038PQRX922;", True)
rd.ExportToDisk(ExportFormatType.PortableDocFormat, "c:\temp\test.pdf")
rd.Close()
End Using
System.Diagnostics.Process.Start("c:\temp\test.pdf")
You could use the Crystal Viewer at this point to deliver the reports and store the report in a database or on the file system (with a db meta data table) and have some predefined connections the user could select from that would be applied when it is run.
You also have the option to write your own front end. In this scenario a user would select a report from your meta data (you could put whatever security on it you wanted, I use AD). Then you can read the report parameters in and lay them out on the web form. When the user fills them in, you then sanatize them and pass them to the report via these extensions and you can output Excel, PDF, Word Doc, RTF, etc. A little more overhead and not the nice preview view, but can work well (I've done something like this in the past). Hope this helps.
About "...let them write their own queries" part of your question.
The solution can be to use some query builder component with friendly user interface which hides from users the complexity of your database and avoid any possible SQL injections.
There are few such products on the market. One of them is called EasyQuery, another one is build by Aspose if I'm not wrong. Try to search in Google for "query bulider for asp.net" or ".net query builder component".

Encrypted SQLite database cannot be attached: "Unable to open the database file"

The database can be open()ed using the same encryption key and it works fine. Tried with multiple encrypted databases - all can be opened, but not attached.
This works when encrypted and when not encrypted (bytearray is null):
connection.open(file, "create", false, 1024, bytearray);
This only works when not encrypted:
connection.attach("db" + newnum.toString(), file, new Responder(attachEncryptedSuccess, openEncryptedError), bytearray);
Any help is appreciated.
UPDATE:
Just found a strange pattern here:
It seems that if I create an encrypted database, and then create new databases and attach them, everything works fine.
The created files, after unloading, will only be properly opened using the command that they were initially created with. Therefore, the encrypted database that I created before using open() will only open with open() method. All the encrypted databases that were initially created using attach() will only be able to be opened using attach(). It also doesn't matter which database was open()ed first, aka which one is the main database. It can even be not encrypted.
This is something very strange. Is this a bug? Or am I doing something wrong here?
One gotcha that I ran into awhile ago, and it sounds like it might be impacting you. If you are creating both db's from AIR then this should work fine, however if you have created one with any external tool - generally most tools will default the PRAGMA ENCODING = UTF8. AIR, being Adobe, does things a little different than just straight up telling you that they create theirs UTF16-LE.
According to sqlite rules, differing encoding types cannot be attached one way or the other. One way to verify is to use sqliteman or some other sqlite editor to verify the pragma settings.
For me, I ended up having to start from a seeded db (empty databases -just the header- were over written by AIR) that was to be initialized from a template database. If I allowed AIR to create my starting db, it was set to UTF16 to which I could not attach a UTF8 template.

Query regarding database connectivity in db4o

I'm creating a db4o object (namely Customer.yap) and if it is already created i just insert new objects into the existing object (namely Customer.yap) .
For both these operations i'm just using:
IObjectContainer db1 = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(),#"C:\Users\admin\Desktop\Db4oObjectFiles\Components.yap");
try
{
db1.Store(comp1);
}
finally
{
db1.Close();
}
Am i doing it right or is there a separate command to check if the object exists and then insert values or can i use the same code for both the operations meaning db4o automatically checks if the object exists at the specified location if it exists it inserts the objects other wise it creates the object at the specified location and then insert the object.
Please help me
Thanks in anticipation
PS: i'm doing this in the context of web application in asp.net and then there is this thought that is always lurking in my mind. should n't i be using the remote connection rather than storing it in actual physical location, but i could n't just figure it how does someone create and store objects in the context of remote connection. i don't know which parameters to specify namely host, port username and password and i even don't know how does some one create database connection what r the statements one should write in the program to connect to this remote object file.
Please please help me and guide me.
A big thanks to anyone in anticipation
db4o automatically updates the object instead of inserting it but there's a catch: you'll have to keep your object container open. db4o works with a local cache that keeps track of stored objects, but once you call close() on the object container that local cash is gone. If you store a previously persisted after a close() on the object container you'll get a duplicate object (db4o thinks it's a new one). If you really have to close the object container and want to update an object you'll have to query for it on db4o, then update, then call store (and then you can close()).
With regards to how to connect to a remote db4o server please see:
http://developer.db4o.com/Documentation/Reference/db4o-7.12/java/reference/Content/client-server/networked.htm
Best! (good luck!)

Resources