How to connect sqlite db to unity - unity3d

I have a preloaded db file, which is present in c drive in my system. If I connect that db file to unity project and try to get data from tables it didn't get any data and I am not getting any exceptions also. If I open this db file (which is present in c drive) with sqlite admin software it shows data in tables. Please suggest any idea, what I am missing. Here is the code I am using for connecting database to my unity project.
Public void OpenDatabase()
{
var dbfileName = "Testuser.db"
var _filePath = File.GetFullPath(dbfileName);
var _connectionString = "URI=file:" + _filePath;
dbcon = new SqliteConnection(_connectionString);
dbcon.Open();
}
When I am trying to create and read db file in the following manner working well.
Working code :
Public void OpenDatabase()
{
var _filePath = Application.PersistanceDataPath + "/" + "owndbfile.db";
if (!File.Exists(_filePath))
{
WWW loadDB = new WWW("jar:file://" + Application.PersistanceDataPath + "!/assets/" + "owndbfile.db");
while (!loadDB.isDone) { }
// then save to Application.persistentDataPath
File.WriteAllBytes(_filePath, loadDB.bytes);
}
var _connectionString = "URI=file:" + _filePath;
dbcon = new SqliteConnection(_connectionString);
dbcon.Open();
}
Please suggest any idea for reading data from tables, if db file is present in one of the drive in a system instead of a present in "application persistance" path.

Related

Unity - Use SQLite database in other folder than StreamingAssets

I made a cross matching words Unity game for Android devices. Currently I am using an SQLite Database in StreamingAssets folder for the words in the game and everything works great.
The problem is that my database in StreamingAssets folder is easily accessible to anyone.
Is there any way to move and access my database from other folder except StreamingAssets?
I am using the code below to access my database on Android:
string databaseName = "/MyDatabase.db";
StartCoroutine(SetDatabase(databaseName));
return Path.Combine("URI=file:" + Application.persistentDataPath + databaseName);
private IEnumerator SetDatabase(string databaseName)
{
string path = Path.Combine("jar:file://" + Application.dataPath + "!/assets" + databaseName);
UnityWebRequest unityWebRequest = UnityWebRequest.Get(path);
yield return unityWebRequest.SendWebRequest();
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
AppHelper.Dbg("SetDatabase()", this + ": " +unityWebRequest.error);
/// Retrieve results as binary data.
byte[] data = unityWebRequest.downloadHandler.data;
/// Writes the DB in the persistent memory.
File.WriteAllBytes(Path.Combine(Application.persistentDataPath + databaseName), data);
}
Attached a screenshot of my .apk file showing my database in StreamingAssets folder.
So I found a solution to the problem I had. I add my database in Resources folder and then use the code below to copy it in persistent memory and therefore the database is not visible in the .apk file.
private void CopyDefinitionsDatabaseFromResources()
{
string RESOURCES_DATABASE_NAME = "words.bytes";
string DATABASE_NAME = "words.db";
TextAsset db = Resources.Load<TextAsset>(Path.GetFileNameWithoutExtension(RESOURCES_DATABASE_NAME));
byte[] data = db.bytes;
// copy the database file from resources to persistent app path
string destination = Path.Combine(Application.persistentDataPath, DATABASE_NAME);
// writing file
File.WriteAllBytes(destination, data);
}

How to retrieve data from sqlite db in unity where db file is present in downloads folder

I am trying to connect SQLite DB file to my unity project where db file is present in downloads folder but I am unable to get data from tables. How can I connect download folder contain DB file to unity project SQLite. My requirement is able to run a project with downloaded db file which is present in the downloads folder. Please suggest any idea. Thanks in advance. Here is the code I am using for connecting db file to SQLite.
Sample code :
Debug.Log("Call to OpenDB:" + databaseName);
var tempdbPath = Path.GetFullPath("log -29-10-2018 - .db");
var tempdbbytes = File.ReadAllBytes(tempdbPath);
var _filePath = tempdbPath;
ApplicationContext.CurrentDatabasePath = _filePath;
//open db connection
_connectionString = "URI=file:" + _filePath;
(where _filePaht = /Users/deepak/Projects/testproject/test/log -29-10-2018 - .db)
ApplicationContext.TempConnectionString = _filePath;
ApplicationContext.ConnectionString = _connectionString;
Debug.Log("Stablishing connection to: " + _connectionString);
dbcon = new SqliteConnection(_connectionString);
dbcon.Open();
}
catch (Exception exception)
{
LoggingManager.Error(exception);
}
}
When I connect persistence folder contain db file it's working well, I am getting a problem when I am trying to connect db file present in the downloads folder.

User Cannot Select SQLite db Location from UWP App

Using code to Preserve access to a StorageFolder stolen from Karl Erickson
public static async Task<StorageFolder> GetOrPickAndRememberFolderAsync(string key)
{
if (StorageApplicationPermissions.FutureAccessList.ContainsItem(key))
{
return await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(key);
}
var picker = new FolderPicker();
picker.FileTypeFilter.Add("*");
StorageFolder folder = await picker.PickSingleFolderAsync();
if (folder != null)
{
StorageApplicationPermissions.FutureAccessList.AddOrReplace(key, folder);
}
return folder;
}
our UWP app is able to browse to and remember the location of a SQLite database chosen by a user. This should give read/write permissions on that folder.
The dbContext is instantiated like this
public dbContext(string dbPath)
{
databasePath = dbPath;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Filename=" + databasePath);
}
This code works if the user chooses the default local storage location for the app.
var picker = new FolderPicker();
picker.FileTypeFilter.Add("*");
StorageFolder folder = await picker.PickSingleFolderAsync();
StorageFolder dbFolder = await GetOrPickAndRememberFolderAsync("LocalDbFolder");
string dbPath = Path.Combine(dbFolder.Path, "MySQLite.db");
using (var db = new dbContext(dbPath))
{
db.Database.Migrate();
}
However if the user chooses any other location (such as their Documents folder) the app fails with the error "SQLite Error 14: 'unable to open database file'."
Why would that be, given the user has given the app explicit permissions on the selected location through the picker?
You can't.
SQLite requires native file access. To use the native file access, you should put the sqlite .db file to the application local folders - Windows.Storage.ApplicationData.Current.LocalFolder or tempfolder.
If you use the file/folder picker, you can get the storagefolder item. But, if the folder is outside of your application, ALL of file accesses are done with OS's broker process. SQLite can't access the such of folders.

Why does sending files from GridFS via MVC4 take so much time?

I want to send images stored in MongoDB using GridFS via a MVC4 Web app to the browser via my LAN environment, but it take ~500ms until the image is sent to the browser.
Google Chrome network inspector says most of the time is spent during "Waiting" while the actual "Receiving" takes ~1ms.
The MongoDB server is in the local network, so what can take so long to send an 10kb image? I use Windows 8 with Visual Studio 2012 and the official mongo-csharp-driver via NuGet.
Here is my code of my "Files" controller which takes an object id and sends the data for this id:
public FileContentResult Files(string id)
{
var database = new MongoClient(MyConnection).GetServer().GetDatabase("MyDB");
var gridFs = new MongoGridFS(database);
var bsonId = new BsonObjectId(id);
var gridInfo = gridFs.FindOneById(bsonId);
var bytes = GridInfoToArray(gridInfo);
return new FileContentResult(bytes, "image/jpeg") { FileDownloadName = gridInfo.Name };
}
private byte[] GridInfoToArray(MongoGridFSFileInfo file)
{
using (var stream = file.OpenRead())
{
var bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
return bytes;
}
}
Code to display the image in a View:
<img src="#Url.Action("Files", new { id = objectIdOfMyImage) })"/>
How different are the results if you cache your Database and MongoGridFS instances?
// create static fields for _database & _gridFs
var database = _database ??
(_database = new MongoClient(MyConnection).GetServer().GetDatabase("MyDB"));
var gridFs = _gridFs ??
(_gridFs = new MongoGridFS(database));
I'm not sure how much overhead it incurs when you instantiate these, but it wouldn't hurt to move it outside of the method you're trying to optimize.

JSON file load issue

I'm currently with this issue, it would be great if someone could give me some pointers or best practice. Titanium SDK version: 1.6.1 iPhone SDK version: 4.2
My app does the following, it is getting a remote JSON file for syncing my SQLite database, but the app is having this error while parsing the file
[INFO] Due to memory conditions, 0 of 0 images were unloaded from cache.
Everything works fine when working with smaller JSON files, but now the file reaches 7MB and the my code quits on me.
Is this because of a titanium JSON parse limitation? I can not provide the database with app installation, because of dynamic content. So this is already an excluded solution.
code:
function syncDatabase() {
if ((Titanium.Network.networkType != Titanium.Network.NETWORK_NONE)) {
Ti.API.info("There is network connection, trying to update database..");
var conn = Ti.Network.createHTTPClient();
conn.setTimeout(20000);
var lastUpdated = Ti.App.Properties.getInt("lastUpdated");
conn.open('GET', 'http://example.com/get/all/' + lastUpdated);
filename = "db";
conn.onload = function(){
try {
if (conn.status == 200)
{
var f = Ti.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
f.write(this.responseData);
}
fillDatabase();
}
catch(e) {
}
};
conn.send();
}
}
function fillDatabase()
{
try {
var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory + "/db");
var json = JSON.parse(file.read().text);
var db = Titanium.Database.open('db');
for( i=0; i < json.length; i++){
Ti.API.info("Found foobar: With id ["+json[i].id+"] ["+json[i].foo+"]");
var syncid = json[i].id;
var foo = json[i].foo;
var bar = json[i].bar;
db.execute('REPLACE INTO objects (id,foo,bar) VALUES (?,?,?)',syncid,foo,bar);
}
Ti.App.Properties.setInt('lastUpdated', Math.floor(new Date().getTime()/1000));
db.close();
}
catch(e) {
Ti.API.info("THERE IS AN ERROR UPDATING THE DATABASE");
}
}
Any help is appreciated.
i have no idea actually but what do you mean with
dynamic content
?
usually it should work with you're database as well