Xamarin, setting up Async DB - c#

i have the following code for the interface in xamarin.
public interface ISQLiteDb
{
SQLiteAsyncConnection GetConnection();
}
then if i go to Android in my DB folder i have this
var documentsPath =
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, "shopItems.db3");
return new SQLiteAsyncConnection(path);
in IOS its pretty much the same
The problem that i'm having is that i cant seem to be able to setup a table that i can use.
As you can see im trying to setup Async DB, i know that for sync one you need to do this
static SQLite.Net.SQLiteConnection database;
//creates the database itself
public DBFunc()
{
database = new SQLite.Net.SQLiteConnection(DependencyService.Get<ISQLitePlatform>(),
DependencyService.Get<SqlSync.IFileHelper>().GetLocalPath("shopItems.db3"));
database.CreateTable<ShopItems>();
}
So the question that i got confused with is how can i setup the same table with async methods? How can i the path where it should be located and how can i connect to it when i need to get data from there?

Related

How can I create a database file with SQLite-net?

I am using SQLite-net nuget package in my UWP application. I want to create a local database file to use as such:
var s = new SQLiteConnection("myDbSQLite.db3", SQLiteOpenFlags.Create);
But it throws the error:
Could not open database file:
C:\Path\MyProject\bin\x86\Debug\AppX\myDbSQLite.db3 (Misuse)
I see in other posts they suggest to use SQLiteConnection.CreateFile("MyDatabase.sqlite"); but I don't see that method?
EDIT
The code
FileStream fs = File.Create(path);
Throws the exception:
UnauthorizedAccessException access to the path is denied
So I think this is a permission issue I am having with UWP. Is there something in the capabilities that I need to set?
Check your permissions on the folder, and also try using this for the constructor
_database = new SQLiteAsyncConnection(
"myDbSQLite.db3",
SQLiteOpenFlags.Create |
SQLiteOpenFlags.FullMutex |
SQLiteOpenFlags.ReadWrite );
Because creating a file in UWP must be done with the UWP API, if you're going to use this nuget library, you have to accommodate by creating it yourself first:
// Create the empty file; replace if exists.
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
storageFolder.CreateFileAsync("myDbSQLite.db3", Windows.Storage.CreationCollisionOption.ReplaceExisting);
My UWP app is actually part of a Xamarin.Forms app that is using shared code, so if your app is solely UWP there's probably a better library, such as this one that Codexer referred.
You should use a folder wher you have write-access to. So please try the following code:
String path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string dbFile = Path.Combine( path, "myDbSQLite.db3");
var s = new SQLiteConnection( dbFile, SQLiteOpenFlags.Create);
This worked for me:
var databasePath = Path.Combine(GetLocalFileDirectory(), "MyData.db");
try
{
// Create the empty file; replace if exists.
db = new SQLiteAsyncConnection(databasePath,
SQLiteOpenFlags.Create |
SQLiteOpenFlags.FullMutex |
SQLiteOpenFlags.ReadWrite);
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
public string GetLocalFileDirectory()
{
var docFolder = FileSystem.AppDataDirectory
var libFolder = Path.Combine(docFolder, "Databases");
if (!Directory.Exists(libFolder))
{
Directory.CreateDirectory(libFolder);
}
return libFolder;
}

Querying TFS 2015 Source Code Repository DateTime Properties with .Net Framework v4.8 and Visual Studio 2019

I am trying to filter for source control files that were either created or modified within a specific time period on particular Team Foundation Server 2015 branches. I am thus far able to access file properties (e.g. url) with the Microsoft.VisualStudio.Services.WebAPI and Microsoft.TeamFoundation.SourceControl.WebApi libraries with a C# .Net Framework 4.8 Console Application using the GitHttpClient class.
The GetItemsAsync() method of this class returns a list of "GitItems" that contain a "path" property that can be passed as an argument into the System.IO class FileInfo to instantiate an object with the properties I need: CreationTime and LastWriteTime. However, the GitItem objects do not include the full file (blob) path that FileInfo (as well as the class File) needs to generate these properties accurately. The path property only includes the file name (e.g. '/.gitignore'). Therefore, in the code below, the variable lastWriteTime and the CreationTime property both return '12/31/1600 7:00:00 PM,' since the path isn't recognized.
static void Main(string[] args)
{
VssCredentials creds = new VssClientCredentials();
creds.Storage = new VssClientCredentialStorage();
VssConnection connection = new VssConnection(new Uri(teamCollection), creds);
// Get a GitHttpClient to talk to the Git endpoints
GitHttpClient gitClient = connection.GetClient<GitHttpClient>();
// Get data about a specific repository
var repositories = gitClient.GetRepositoriesAsync(teamProject).Result;
GitVersionDescriptor descriptor = new GitVersionDescriptor()
{
VersionType = GitVersionType.Branch,
Version = "develop",
VersionOptions = GitVersionOptions.None
};
foreach (var repository in repositories)
{
var branches = gitClient.GetBranchesAsync(repository.Id).Result;
var items = gitClient.GetItemsAsync(repository.Id, recursionLevel: VersionControlRecursionType.Full, versionDescriptor: descriptor, includeContentMetadata: true).Result;
foreach (var item in items)
{
var fullPath = Path.GetFullPath(item.Path);
FileInfo file = new FileInfo(fullPath);
DateTime lastWriteTime = file.LastWriteTime;
}
Console.WriteLine(repository.Name);
}
}
}
}
According to your code, you are using GitHttpClient.GetItemsAsync method.
public Task<GitItemsCollection> GetItemsAsync(
Guid repositoryId,
string path,
GitVersionDescriptor version,
VersionControlRecursionType recursionLevel,
bool includeContentMetadata,
bool includeLatestChange,
Object userState
)
This will return a server side git path. File info class with LastWriteTime properties
Gets or sets the time when the current file or directory was last written to. This should be a local system path.
That's why the path isn't recognized. Which may return a date kind of '12/31/1600 7:00:00 PM,'
Your question is similar to this VSTS API - repository creation date
Don't think it is possible to get the exact date of the moment the
operation create repo was completed. However, logically the birthday
of the repository is usually considered its first commit date.
If that's what you're looking for, you can achieve your goal with a
usual Git command:
git log -1 --reverse --format="format:%ci"
Besides, you could also get a git commit with detail info through Rest API. Also take a look at this blog, which maybe helpful.

Path to store SQLite database in Xamarin Android

I'm trying to store a local SQLite database in the internal storage of the device. When I was using an emulator , this:
static string dbName = "totems.sqlite";
string dbPath = Path.Combine (Android.OS.Environment.ExternalStorageDirectory.ToString (), dbName);
worked fine. But when I tried to debug on my Nexus 5, it didn't work, because it doesn't have external storage. I searched where to store it so it could run on my Nexus as well. I replaced it with:
static string dbName = "totems.sqlite";
string dbPath = Path.Combine ("/data/data/com.companyname.totem/databases/", dbName);
But now it doesn't work on my Nexus 5 and it doesn't work on my emulator. It says it can't find the path.
What am I doing wrong?
Thanks in advance.
I know this is an old thread, but the old answer has a typo. The working syntax should be :
string path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "DatabaseName.txt");
Im using the following code:
string path = Path.Combine(System.Enviroment.GetFolderPath(System.Enviroment.SpecialFolder.Personal), "data.txt");
I think that should write into the internal storage like you want
From docs.com
LocalApplicationData: The directory that serves as a common
repository for application-specific data that is used by the current,
non-roaming user.
Personal: The directory that serves as a common repository for
documents. This member is equivalent to MyDocuments.
From this I use:
var db_directory = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData),"databases"))
var db_path = Path.Combine(db_directory,"data.db");
Also from this sample (XF)
docs.com xamarin tutorial
public static Database Database
{
get
{
if (database == null)
{
database = new Database(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "people.db3"));
}
return database;
}
}

Windows Store App c# replace SQL Database in local storage

I am trying to overwrite the database in my local folder with one that is in my pictures directory I use the following
StorageFolder storageFolder = KnownFolders.PicturesLibrary;
String picName = "SqlLiteWin8-1.db";
var file2 = await storageFolder.TryGetItemAsync(picName) as IStorageFile;
StorageFile fileCopy = await file2.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, "SqlLiteWin8-1.db", Windows.Storage.NameCollisionOption.ReplaceExisting);
It seems to work and the file is copied and overwrite the old one
Problem is when I run the app it still shows the old data
I checked by manually deleting the db in the local state folder of the app then running the code and it copies it to the folder.
I think its still using the database in the app package and not the one in the local folder
The database in the pictures directory is identical to the one stored in the app except 1 record is modified
I want to overwrite it so that I can just supply a new db file to users and the app will use the new data or is there a way of bypassing this and read the DB straight from the pictures directory instead of the local folder
one though was it uses the following code to check if the db exists and copies if it doesnt could this be what is causing it not to work
public static async Task<bool> checkDataBaseConnection()
{
bool isDatabaseExisting = false;
try
{
var uri = new Uri("ms-appx:///SqlLiteWin8-1.db"); //in application folder
var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
var destinationFolder = ApplicationData.Current.LocalFolder;//local appdata dir
//await file.DeleteAsync();
// var f = await destinationFolder.GetFileAsync("data.db3");
await file.CopyAsync(destinationFolder);
}
catch (Exception ex)
{
throw ex;
isDatabaseExisting = false;
}
if (!isDatabaseExisting)
{
StorageFile databaseFile = await Package.Current.InstalledLocation.GetFileAsync("AFSMOJO.db");
await databaseFile.CopyAsync(ApplicationData.Current.LocalFolder);
}
return isDatabaseExisting;
}
As always your help is greatly appreciated
Mark
Ignore my stupidity I found what was wrong I was connecting to the internal database instead of the local one
I changed
var db = new SQLiteConnection("SqlLiteWin8-1.db");
to
var db = new SQLiteConnection(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "SqlLiteWin8-1.db"));
and now i can change my db in the picture folder and it copies it to the local one and uses the new data
Thanks
Mark

How to Create and Execute an SSIS Package on remote sql Server source and destination using EzAPI

I need to create a Console application that can copy a table from one remote sql server instance to another remote sql server instance.
I'm using a library called EzAPI
Both connections (Source and Destinations) and table name will be provided as parameters to the Console application.
Here is my try:
public class OleDBToOleDB : EzSrcDestPackage<EzOleDbSource, EzSqlOleDbCM, EzOleDbDestination, EzSqlOleDbCM>
{
public OleDBToOleDB(Package p) : base(p) { }
public static implicit operator OleDBToOleDB(Package p) { return new OleDBToOleDB(p); }
public OleDBToOleDB(string SrcServer, string SrcDB, string SrcTable,string SrcUser,string SrcPassword, string DstServer, string DstDB, string DstTable,string DstUser,string DstPassword)
{
SrcConn.SetConnectionString(SrcServer, SrcDB);
SrcConn.ServerName = SrcServer;
SrcConn.InitialCatalog = SrcDB;
SrcConn.UserName = SrcUser;
SrcConn.Password = SrcPassword;
Source.Table = SrcTable;
DestConn.SetConnectionString(DstServer, DstDB);
DestConn.ServerName = DstServer;
DestConn.InitialCatalog = DstDB;
DestConn.UserName = DstUser;
DestConn.Password = DstPassword;
Dest.Table = DstTable;
}
}
static void Main(string[] args)
{
OleDBToOleDB p = new OleDBToOleDB("localhost", "TestDB", "Address", "sa", "123", "localhost", "DestDB", "Address", "sa", "123");
p.Execute();
Console.Write(string.Format("Package2 executed with result {0}\n",p.ExecutionResult));
}
The problem with this code is:
It does not create the table on the destination server, so I should
create it manually by myself.
This code runs successfully on the localhost, but when I try to
change the server name to a remote server it raises this error:
Unhandled Exception: System.Runtime.InteropServices.COMException
(0xC020801C): Exception from HRESULT: 0xC020801C
After searching on the web I found that this error means that this error is an Integration services AcquireConnections exception.
So how can I get this code running on a remote sql server instance and have the package create the table on the destination server before transferring the data.
Thank you in advance.
SSIS needs both tabled during the package generation, since it has to get the whole metadata for each column in your tables. You can set the ValidateMetadata property to false, in this case it will not validate it, but you will need to fill all the data by yourself. This is not easy.
I think the most easy thing you can do is:
1)generate the package with local connections and turn off the validation for your destination component
2)now set the new connection strings to your source and destination compoennts
3)run the package
this is a not really clean workaround. This should be usually done with a configurations, but since you do not save your package you can try this as well.
I think it can be also easier to implement your task with SqlBuldCopy without SSIS

Categories