Solved | Unity SQLite conection unable to open database file - android

I am new to Unity and SQLite.
I am doing an Android app, that should work offline. It is the first time I use Unity and SQLite.
I am just trying to connect to my SQLite database file, TrilhoVerde.db. I created it using SQLiteAdministrator. I created a database but is empty. I would create the necessary tables in the C# file (because of the foreign keys). This is the code I have:
private IDbConnection connection;
private IDbCommand command;
private IDataReader reader;
// Start is called before the first frame update
void Start()
{
Connection();
}
private void Connection()
{
string dbFile = "URI=File:"+ Application.dataPath +"/Plugins/TrilhoVerde.db:";
connection = (IDbConnection) new SqliteConnection(dbFile);
connection.Open();
command = connection.CreateCommand();
string createTable = "select * from Avatar;";
command.CommandText = createTable;
reader = command.ExecuteReader();
}
But when I run it in Unity, I got this error:
SqliteSyntaxException: unable to open database file
Mono.Data.SqliteClient.SqliteCommand.GetNextStatement (System.IntPtr pzStart, System.IntPtr& pzTail, System.IntPtr& pStmt) (at <9f65d62b5efa4334801a8fece4acee8a>:0)
Mono.Data.SqliteClient.SqliteCommand.ExecuteReader (System.Data.CommandBehavior behavior, System.Boolean want_results, System.Int32& rows_affected) (at <9f65d62b5efa4334801a8fece4acee8a>:0)
Mono.Data.SqliteClient.SqliteCommand.ExecuteNonQuery () (at <9f65d62b5efa4334801a8fece4acee8a>:0)
carrega.Connection () (at Assets/scipts/carrega.cs:30)
carrega.Start () (at Assets/scipts/carrega.cs:17)
I was using the tutorials in these videos:
https://www.youtube.com/watch?v=QtDtBvAyzOQ
https://www.youtube.com/watch?v=CtDSQkLdlZg
I think I did all the steps. I know that there are a lot of questions related to this matter, but so far none if them solved my problem. If something is missing to understand what I did and what is wrong, please tell me.
Does anyone know what I am doing wrong.
And I'm sorry if this is something really simple, but, like I said, I am new to Unity and SQLite.
UPDATE
I created a new database file using another program and I commented the command part of the code. It now does not threw any error. Reversing that comment, error again.
The problem is in this specific line:
reader = command.ExecuteReader();
I also added the tables in database file, not in C#. Stil don't know what the problem is.

I am really sorry to de ones that lost time on this, and I am embarrassed too. The name of the database file was wrong. I was supposed to TrilhoVerde.db, but I had TrilhoVerde.bd: in the script.

Related

Xamarin SqlServer cant get a connection

I'm building an app with the Entity Framework on Xamarin that lets me compare some data. But when I start my "fetchdata" function, I receive the Error:
System.Data.SqlClient.SqlException (0x80131904): Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)
I see many posts about Xamarin / Android & that it is not possible to get a connection to a SQL Server. Is there any way to fetch data from a SQL Server with .NET Core on Xamarin?
This is the string I put into SQL_Class folder with Sql_Common.cs
Fill up the brace brackets with actual parameters (removing the brace brakets too).
public static string SQL_connection_string = #"data source={server_address};initial catalog={database_name};user id={user_id};password={password};Connect Timeout={seconds}";
Then I access whenever I need it from any xamarin code just like we use in our asp.net c#
This works for me on my app without any issues.
using (SqlConnection Sql_Connection = new SqlConnection(Sql_Common.saralEHR_connection_string))
But as #Jason mentioned in his first reply, I too would get once again check the security part. I fexperienced before publishing Package to Google Play, they encrypt the App files with Hash Key Code and then only it gets upload to server
Yes it is possible (HuurrAYY!):
Im new in .net core, c# and so on and for me it was a hell of a work to get it working..
So here for the other noobs who are seeking for Help:
GuideĀ“s i used:
Building Android Apps with Entity Framework
https://medium.com/#yostane/data-persistence-in-xamarin-using-entity-framework-core-e3a58bdee9d1
https://blog.xamarin.com/building-android-apps-entity-framework/
Scaffolding
https://cmatskas.com/scaffolding-dbcontext-and-models-with-entityframework-core-2-0-and-the-cli/
How i did it:
Build your normal Xamarin app.
create new .net solution like in the tutorials (DONT WRITE YOUR Entity Framework CLASSES)
create a third solution what has to be a .net core console application
Scaffold your DB in your CONSOLE application move all created classes & folders in your "xamarin .net" solution & change the namespaces
Ready to Go!
Side Node: NuGets you need in every solution:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
[EDIT: NuGets you need in every solution]
I am doing this way (working snippet):
string connectionString = #"data source={server};initial catalog={database};user id={user};password={password};Connect Timeout=10";
string databaseTable = "{table name}";
string selectQuery = String.Format("SELECT count(*) as Orders FROM {0}", databaseTable);
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
//open connection
connection.Open();
SqlCommand command = new SqlCommand(selectQuery, connection);
command.Connection = connection;
command.CommandText = selectQuery;
var result = command.ExecuteScalar().ToString();
//check if there is result
if(result != null)
{
OrdersLabel.Text = result;
}
}
}
catch (Exception ex)
{
OrdersLabel.Text = ex.Message;
}
It is working fine, but API call more elegant.
I hope it helps.

Android Read Result From MySQL

My code used to work, it does not work anymore, I tried troubleshooting and can't figure out why.
I have this piece of code in my PHP:
$android_id_01 = $_GET['pmysql_room_id'];
$android_id_02 = "";
$f = fopen("00_android_id_01.txt", "w");
fwrite($f, print_r($android_id_01, true));
fclose($f);
$f = fopen("00_android_id_02.txt", "w");
fwrite($f, print_r($android_id_02, true));
fclose($f);
For troubleshooting I created two android IDs ($android_id_01 and $android_id_02) which are both empty (The first one is From Android and the second one I created directly from PHP).
Now when I launch my Android device, the PHP file is executed from server side and both the text files are created empty and identical. Now my code only works when I use $android_id_02 and not $android_id_01 from the code below:
if ($android_id == '')
{
//my code
}
(Yes when I use either one of the $android_id_01 OR $android_id_02 I rename it to $android_id and comment out the other one)
My question is, although this was working yesterday, why does it work with $android_id_02 = ""; and not $android_id_01 = $_GET['pmysql_room_id']; even though they are both empty????
I don't know what changed from yesterday to today.
Ok after a bit of troubleshooting I found a solution, strange though.
On the server side "display_errors" under PHP settings must be turned off. Somehow having this on interferes with the json_encode sent back to android client. (even though my code is not generating any errors)

How can I import XML schema without network access?

I'm implementing schema validation using libxml2. The schema I'm validating against imports two other schemas with lines like:
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.somewebsite.com/xsd/xml.xsd"/>
All three schema files are located in the same directory on the device.
This works well when the device has internet access, but fails when it does not, as libxml2 still attempts to download the imported schemas from the schemaLocation even though I'm passing in XML_PARSE_NONET.
I tried getting libxml2 to load the files locally by editing the schemaLocation attribute to xml.xsd, ./xml.xsd, and file:///data/data/com.company.appname/files/xml.xsd, but all three resulted in the same libxml2 error:
domain: 16
code: 3069 (XML_SCHEMAP_INTERNAL)
message: Internal error: xmlSchemaParse, An internal error occurred.
I also tried removing the schemaLocation attribute entirely, on the off-chance that libxml2 might search for the imported schemas alongside the original schema, but that resulted in the following error when the schema parser hit a line that referenced the imported entities:
<xs:attribute ref="xml:lang" use="required"/>
domain: 16
code: 3004 (XML_SCHEMAP_SRC_RESOLVE)
message: attribute use (unknown), attribute 'ref': The QName value '{http://www.w3.org/XML/1998/namespace}lang' does not resolve to a(n) attribute declaration.
I also looked into manually merging the three schemas into a single file, but as they use different namespaces, this is not possible.
The standard solution for this seems to be the XML catalog, but I've read through libxml2's catalog documentation, and I can't figure out how (or even whether it's possible) to add mappings that will be used by my app when deployed to a device. I think I might need to implement an xmlExternalEntityLoader, but the documentation for that is quite slim.
How can I get libxml2 to import these schemas without network access? Obviously I'd ideally like a robust solution that works with the unedited schema, but I've be content with something quick-and-dirty that involves editing the schema, like my original attempts described above.
The errors described above are from an Android device (using JNI), but I'm having similar problems on iOS, where the solution will also need to work.
One way to do this is to intercept libxml2's call to open the imported URL with a custom xmlExternalEntityLoader.
The basic code for doing this is as follows:
#include <libxml/xmlIO.h>
#include <libxml/parserinternals.h>
xmlExternalEntityLoader defaultLoader = NULL;
xmlParserInputPtr
xmlMyExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
const char *fileID = NULL;
/* lookup for the fileID
* The documentation suggests using the ID, but for me this was
* always NULL so I had to lookup by URL instead.
*/
ret = xmlNewInputFromFile(ctxt, fileID);
if (ret != NULL)
return(ret);
if (defaultLoader != NULL)
ret = defaultLoader(URL, ID, ctxt);
return(ret);
}
int main(..) {
...
/*
* Install our own entity loader
*/
defaultLoader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmlMyExternalEntityLoader);
...
}
(Slightly adjusted from the sample code in The entities loader section of libxml2's I/O Interfaces documentation.)

Titanium install DB

I have some trouble with installing a database with Ti.Database.install(). Here's what I'm doing:
Open new default alloy project
Add some code to controllers/index.js so the file looks like this
var db = Ti.Database.install('/testimusDB.sqlite', 'testimusDB');
var rs = db.execute('SELECT * FROM testimusTable');
db.close();
while (rs.isValidRow())
{
var name = rs.fieldByName('name');
var age = rs.fieldByName('age');
alert(name + ' is ' + age + 'years old');
rs.next();
}
rs.close();
$.index.open();
create a DB with FF Plugin SQLite Manager called testimusDB.sqlite
and copy it to the REsources Folder of the Project
Start the App via Titanium Studio on a Samsung S3
What I get is
Runtime Error: LOCATION: [101,19] ti:/invoker.js
MESSAGE: Uncaught Error: Resources/testimusDB.sqlite SOURCE: return
delegate.apply(invoker._thisObj_,args);
People with the same problem solved it by reducing the size of the DB (mine is 64 KB) or by using absolute path (I tried absolute-/relative- path and sqlite-/db-/sql- suffix). Any ideas how to solve this problem?
Okay I got it: You can't use install() when you're using alloy! (If anybody knows an official source for this information please let me know). You need to use models to sync the database. This guy and this guide helped me a lot.
Thanks for the answers.
Close connection to db at the end of operation:
rs.close();
db.close();
Size of the database doesn't matter. I'm using much bigger one: >10MB.

Generate errorhandler for XMLAplicationContext

I'm a flex developer and have a small problem.
I use XMLApllicationContext to load an XML file.
I load my context and then add the config location to it.
In this files I take care of creating an URL to connect to.So I made an eventlistner for my XMLApplicationContext with Event.COMPLETE so I know when he's done and he can connect.
No I'm a little bit dummytesting and if the user has given a wrong host and port the URL will not exist. So there will never be an Event.COMPLETE action.
For that I would love to know how I can solve this.
Now I have this code:
public function execute():*
{
m_context = new XMLApplicationContext("application-context.xml");
m_context.addConfigLocation("application-context-services.xml");
m_context.addEventListener(Event.COMPLETE, onComplete);
m_context.addEventListener(......);//need to know what has to come between the brackets
m_context.load();
ServiceLocator.getInstance().context = m_context;
}
I allready tried some things but haven't found a solution yet.
Thank you in advance.
Kind regards,
Thibault Heylen
Did you try the IOErrorEvent?
If that doesn't work for you, you could try creating a file reference and check if it exists ...
var f:File = new File("application-context.xml");
if (f.exists) {
//...
}
Im not quite sure, but if this is a local file you maybe have to add "app:/path/to/file/" in front of your url/file name

Categories

Resources