Xamarin.Forms using SQLite.Net.Async - sqlite

I have followed the instructions here http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/databases/ - to connect to the SQLite database synchronously.
public SQLiteConnection GetConnection()
{
var dbFilname = "localDB.db3";
string docsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var path = Path.Combine(docsPath, dbFilname);
var plat = new SQLitePlatformAndroid();
var conn = new SQLiteConnection(plat, path);
return conn;
}
I want to change it to an asynchronous connection (SQLiteAsyncConnection) but can't get it to work.
According to the instructions here - https://components.xamarin.com/gettingstarted/sqlite-net -it just needs the path as a parameter
var conn = new SQLiteAsyncConnection(path);
that doesn't work, the error says that the parameters expected are:
a connection function, a TaskScheduler and TaskCreationOptions
I have no idea what to do and have not been able to find any examples that work.
Thanks in advance

You could simply reuse the GetConnection method you already have and create async connection like this:
var asyncDb = new SQLiteAsyncConnection(() => GetConnection());

Xamarin Platforms Android Config, iOS and WP basicaly equal
public SQLiteAsyncConnection GetConnectionAsync()
{
const string fileName = "MyDB.db3";
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, fileName);
var platform = new SQLitePlatformAndroid();
var param = new SQLiteConnectionString(path, false);
var connection = new SQLiteAsyncConnection(() => new SQLiteConnectionWithLock(platform, param));
return connection;
}

Related

Asp.net core disable change string in Uri

I have a Encoded string like this:
https://xx.yyy.ir/xx/ff/addUser?name=%d8%b3%d9%84%d8%a7%d9%85
But when I use Uri to convert it to a URL and send it
result = "https://xx.yyy.ir/xx/ff/addUser?name=%d8%b3%d9%84%d8%a7%d9%85"
var client = new HttpClient
{
BaseAddress = new Uri(result.ToString()),
};
var response = await client.GetAsync("");
it send this request :
https://xx.yyy.ir/xx/ff/addUser?name=سلام
why this happen? how to prevent from this?
This is what's causing your problem: new Uri(result.ToString())
Let's try to do this in a proper manner and see what happens.
var builder = new UriBuilder("https://xx.yyy.ir/xx/ff/addUser") { Port = -1 };
var query = HttpUtility.ParseQueryString(builder.Query);
query["name"] = "سلام";
builder.Query = query.ToString();
using var httpClient = new HttpClient();
var response = await client.GetAsync(builder.ToString());
builder.ToString() returns https://xx.yyy.ir/xx/ff/addUser?name=%d8%b3%d9%84%d8%a7%d9%85
So basically, the above code boils down to this:
using var httpClient = new HttpClient();
var response = await client.GetAsync("https://xx.yyy.ir/xx/ff/addUser?name=%d8%b3%d9%84%d8%a7%d9%85");
Tested and verified on my computer.

Notification hub device registration with installation

After reading this I've been trying to create an installation in my xamarin.android app but I keep getting an 'Unauthorized error' I feel that I'm missing something. Any help is appreciated.
Previously I was able to register with the hub using
var regID = hub.Register(token, tags.ToArray()).RegistrationId;
so I'm sure my hub has been setup correctly and that I am using the correct connectionstring.
My installation object
install.installationId = installationId; //guid
install.tags = Tags;
install.platform = "gcm";
install.pushChannel = token; //refresh token from fcm
Call to Create installation
private async Task<HttpStatusCode> CreateOrUpdateInstallationAsync(DeviceInstallation deviceInstallation,
string hubName, string listenConnectionString)
{
if (deviceInstallation.installationId == null)
return HttpStatusCode.BadRequest;
// Parse connection string (https://msdn.microsoft.com/library/azure/dn495627.aspx)
ConnectionStringUtility connectionSaSUtil = new ConnectionStringUtility(listenConnectionString);
string hubResource = "installations/" + deviceInstallation.installationId + "?";
string apiVersion = "api-version=2015-04";
// Determine the targetUri that we will sign
string uri = connectionSaSUtil.Endpoint + hubName + "/" + hubResource + apiVersion;
//=== Generate SaS Security Token for Authorization header ===
// See, https://msdn.microsoft.com/library/azure/dn495627.aspx
string SasToken = connectionSaSUtil.getSaSToken(uri, 60);
using (var httpClient = new HttpClient())
{
string json = JsonConvert.SerializeObject(deviceInstallation);
httpClient.DefaultRequestHeaders.Add("Authorization", SasToken);
var response = await httpClient.PutAsync(uri, new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
return response.StatusCode;
}
}

Xamarin Android - where to store Local DB so i can view it

I'm currently saving my local sqlite db in Environment.GetFolderPath(Environment.SpecialFolder.Personal) with this code.
Now i'm trying to copy the Db to my PC so i can watch what's inside it. But i'm not able to see this Folder unless it's rooted.
Where is the best place to save the DB so i can view it every now and then?
Here is my android DB code:
[assembly: Dependency(typeof(SQLite_Android))]
namespace AppName.Droid
{
public class SQLite_Android : ILocalDb.Interfaces.ILocalDb
{
#region ISQLite implementation
public SQLite.SQLiteConnection GetConnection()
{
var sqliteFilename = "MyDb.db3";
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, sqliteFilename);
// Create the connection
var conn = new SQLite.SQLiteConnection(path);
// Return the database connection
return conn;
}
#endregion
}
}
You can use external storage option:
var sqliteFilename = "MyDb.db3";
var extStoragePath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var path = Path.Combine(extStoragePath, "MyNewFolder");
var filename = Path.Combine(path, sqliteFilename);
// Create the connection
var conn = new SQLite.SQLiteConnection(path);
// Return the database connection
return conn;
This way file will be visible via file explorer

Application is not working when using SQlite databse in windows phone 8

I developed my first application in windows phone 8.1.It is working fine in my local emulator and device but whenever i upload the app in store it is not working.whenever I open the app it is suddenly come back.I used the SQlite database in my application.When I am not using the Sqlite database it is working fine(I uploaded in beta).Please any one help me solve from this issue.
Thank you in advance
sqlite code:
public async void createdatabase()
{
SQLiteConnectionString c = new SQLiteConnectionString(System.IO.Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "newDB.db"), true);
var conn = new SQLiteAsyncConnection(c.DatabasePath);
await conn.CreateTableAsync<Operators>();
}
public async void Drop()
{
SQLiteConnectionString c = new SQLiteConnectionString(System.IO.Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "newDB.db"), true);
using (var dbConn = new SQLiteConnection(c.DatabasePath))
{
SQLiteCommand cmd = new SQLiteCommand(dbConn);
cmd.CommandText = "DROP TABLE IF EXISTS Operators";
int response = cmd.ExecuteNonQuery();
}
public async void insert()
{
rechargeOperator1.Items.Clear();
rechargeCircles1.Items.Clear();
SQLiteConnectionString c = new SQLiteConnectionString(System.IO.Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "newDB.db"), true);
var conn = new SQLiteAsyncConnection(c.DatabasePath);
var client = new pavandatabase.JsonWebClient();
var resp1 = await client.DoRequestAsync(Url.weburl + "getRechargeCircleList");
string result1 = resp1.ReadToEnd();
JArray jsonArray = JArray.Parse(result1);
for (int j = 0; j < jsonArray.Count; j++)
{
JObject jobj = (JObject)jsonArray[j];
string id = (string)jobj["CircleID"];
string statename = (string)jobj["CircleName"];
//circles combobox......
rechargeCircles1.Items.Add(statename);
Operators op = new Operators();
op.Operatorid = int.Parse(OperatorID);
op.Operatorname = Operator;
op.servicetypeid = int.Parse(ServiceTypeID);
await conn.InsertAsync(op);
}
Try to put the break points on the first line of your application and keep on pressing f10 and see at which line it com out and post that line.
Hope it will help you to get the solution.
Thanks,

How to consume a LOB Adapter SDK-based design-time interfaces

I'm trying to build a web-based GUI to consume custom LOB Adapter SDK-based connectors.
In particular, I would like to browse the metadata using the IMetadataResolverHandler interface.
I'm having two problems:
The first problem happens when trying to instantiate the custom adapter. My plan is to obtain an instance of the IConnectionFactory interface, through which I could get a new IConnection and connect to the target LOB system.
Since the most interesting methods in the Adapter base class are protected, I can only seem to succeed using reflection (please, see the sample code below).
The second problem happens when trying to browse the metadata from the target system. The method Browse on the IMetadataResolverHandler interface expects an instance of a MetadataLookup object that I have no idea how to obtain.
Please, see the sample code below:
static void Main(string[] args)
{
var extension = new SqlAdapterBindingElementExtensionElement();
var adapter = (Adapter) Activator.CreateInstance(extension.BindingElementType);
var isHandlerSupportedMethodInfo = adapter.GetType().GetMethod("IsHandlerSupported", BindingFlags.NonPublic | BindingFlags.Instance);
var buildConnectionUri = adapter.GetType().GetMethod("BuildConnectionUri", BindingFlags.NonPublic | BindingFlags.Instance);
var buildConnectionFactory = adapter.GetType().GetMethod("BuildConnectionFactory", BindingFlags.NonPublic | BindingFlags.Instance);
if (isHandlerSupportedMethodInfo == null || buildConnectionUri == null || buildConnectionFactory == null)
{
Console.WriteLine("Not a LOB adapter.");
Environment.Exit(1);
}
var isHandlerSupportedTHandler = isHandlerSupportedMethodInfo.MakeGenericMethod(typeof(IMetadataResolverHandler));
var isMetadataBrowseSupported = (bool)isHandlerSupportedTHandler.Invoke(adapter, new object[] { });
if (!isMetadataBrowseSupported)
{
Console.WriteLine("Metadata retrieval not supported.");
Environment.Exit(1);
}
var bindingElement = (SqlAdapterBindingElement)adapter;
bindingElement.AcceptCredentialsInUri = false;
bindingElement.InboundOperationType = InboundOperation.TypedPolling;
bindingElement.PolledDataAvailableStatement = "EXEC [dbo].[usp_IsDataAvailable]";
bindingElement.PollingStatement = "EXEC [dbo].[usp_SelectAvailableData]";
bindingElement.PollingIntervalInSeconds = 10;
var binding = new CustomBinding();
binding.Elements.Add(adapter);
var parameters = new BindingParameterCollection();
var context = new BindingContext(binding, parameters);
var credentials = new ClientCredentials();
credentials.UserName.UserName = "username";
credentials.UserName.Password = "password";
var address = (ConnectionUri) buildConnectionUri.Invoke(adapter, new []{ new Uri("mssql://azure.database.windows.net//SampleDb?InboundId=uniqueId")});
var connectionFactory = (IConnectionFactory)buildConnectionFactory.Invoke(adapter, new object[] { address, credentials, context });
var connection = connectionFactory.CreateConnection();
connection.Open(TimeSpan.MaxValue);
MetadataLookup lookup = null; // ??
var browser = connection.BuildHandler<IMetadataBrowseHandler>(lookup);
connection.Close(TimeSpan.MaxValue);
}
Answering my own question, I figured it out by inspecting the code of the "Consume Adapter Service" wizard. The key is to use the IMetadataRetrievalContract interface which, internally, is implemented using up to three LOB-SDK interfaces, and in particular IMetadataResolverHandler.
Here is code that works without reflection:
var extension = new SqlAdapterBindingElementExtensionElement();
var adapter = (Adapter) Activator.CreateInstance(extension.BindingElementType);
var bindingElement = (SqlAdapterBindingElement)adapter;
bindingElement.AcceptCredentialsInUri = false;
bindingElement.InboundOperationType = InboundOperation.TypedPolling;
bindingElement.PolledDataAvailableStatement = "EXEC [dbo].[usp_IsDataAvailable]";
bindingElement.PollingStatement = "EXEC [dbo].[usp_SelectAvailableData]";
bindingElement.PollingIntervalInSeconds = 10;
var binding = new CustomBinding();
binding.Elements.Add(adapter);
const string endpoint = "mssql://azure.database.windows.net//SampleDb?InboundId=unique";
var factory = new ChannelFactory<IMetadataRetrievalContract>(binding, new EndpointAddress(new Uri(endpoint)));
factory.Credentials.UserName.UserName = "username";
factory.Credentials.UserName.Password = "password";
factory.Open();
var channel = factory.CreateChannel();
((IChannel)channel).Open();
var metadata = channel.Browse(MetadataRetrievalNode.Root.DisplayName, 0, Int32.MaxValue);
((IChannel) channel).Close();
factory.Close();

Resources