I'm creating a Unity project (version 2019) + SQLite + VSCode.
I added the appropriate plugins in the project folder but I still have the following error:
Assets \ BancoSQLite.cs (33,17): error CS0433: The type 'IDataReader' exists in both 'System.Data, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089' and 'netstandard, Version =
2.0.0.0.0 , Culture = neutral, PublicKeyToken = cc7b13ffcd2ddd51 '
I did everything but I can't come up with a solution.
Script SQLite
using System.Collections;
using System.Collections.Generic;
using System.Data;
using Mono.Data.SqliteClient;
using UnityEngine;
using UnityEngine.UI;
public class BancoSQLite : MonoBehaviour {
//private IDbConnection connection;
//private IDbCommand command;
//private IDataReader reader;
public InputField ifLogin;
public InputField ifSenha;
public string senha;
public string login;
private string dbName = "URI=file:SQLiteDB.db";
private void Connection () {
Debug.Log("Entrou");
using (var connection = new SqliteConnection (dbName)) {
connection.Open ();
using (var command = connection.CreateCommand ()) {
connection.Open ();
command.CommandText = "CREATE TABLE IF NOT EXISTS usuario (id INTEGER PRIMARY KEY AUTOINCREMENT, login VARCHAR(30), senha VARCHAR(30));";
command.ExecuteNonQuery();
command.CommandText = "SELECT " + ifLogin + " FROM usuario;";
//IDataReader login = command.ExecuteNonQuery();
IDataReader reader = command.ExecuteNonQuery();
Debug.Log(login);
}
}
}
// Start is called before the first frame update
void Start () {
Connection ();
}
// Update is called once per frame
void Update () {
}
}
None of this is for the specific issue in the question, but when you solve that the code will run into these things, too:
select ifLogin from usario is wrong. You need select * from usuario where login = ifLogin. And make sure to use parameterized queries; sooner or later string concatenation for this WILL break your database.
Additionally, if you want to see the results use ExecuteReader(), ExecuteScalar(), or Fill() a dataset/table. ExecuteNonQuery() is for INSERT/UPDATE/DELETE and doesn't give you results for SELECT.
Related
i am trying to insert this command in a dynamic way in a unity project:
public static string insertPlayerCmd = "INSERT INTO Player (Name) VALUES (?);";
I am using this method on a repository to insert a name into the database:
public AccountContents SaveAccount(string newName)
{
string name = newName;
var transaction = Finder.DB.DatabaseConnection.BeginTransaction();
var command = Finder.DB.DatabaseConnection.CreateCommand();
AccountContents newAccountContents = null;
try
{
command.CommandText = ConstantDbRequests.insertPlayerCmd;
command.Parameters.Add(newName);
var newAccount = command.ExecuteReader();
transaction.Commit();
newAccountContents = new AccountContents(newAccount.GetInt32(0), newAccount.GetString(1));
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
return newAccountContents;
}
the line command.Parameters.Add(newName); throws an invalid cast exception.
I verified my database in SQLite, and the column to insert is of Text type, all the names on the SQL command are writen correctly, but i can't add the parameter to replace the ? wildcard
new to xamarin forms with SQLite. I need some guidance on how to use SQLite in Xamarin forms. Below is the code.
1) Create Interface
using System;
using SQLite.Net;
namespace SQLiteSample
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
2) Implementing ISQLite interface
using System;
using Xamarin.Forms;
using SQLiteEx.Droid;
using System.IO;
[assembly: Dependency(typeof(SqliteService))]
namespace SQLiteEx.Droid
{
public class SqliteService : ISQLite
{
public SqliteService() { }
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "myDB.db3";
// Documents folder
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, sqliteFilename);
Console.WriteLine(path);
if (!File.Exists(path)) File.Create(path);
var plat = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
var conn = new SQLite.Net.SQLiteConnection(plat, path);
// Return the database connection
return conn;
}
}
}
3) Class for Database Operation :CRUD
using SQLite.Net;
using Xamarin.Forms;
namespace SQLiteEx
{
public class DataAccess
{
SQLiteConnection dbConn;
public DataAccess()
{
dbConn = DependencyService.Get<ISQLite>().GetConnection();
// create the table(s)
dbConn.CreateTable<Employee>();
}
public List<Employee> GetAllEmployees()
{
return dbConn.Query<Employee>("Select * From [Employee]");
}
public int SaveEmployee(Employee aEmployee)
{
return dbConn.Insert(aEmployee);
}
public int DeleteEmployee(Employee aEmployee)
{
return dbConn.Delete(aEmployee);
}
public int EditEmployee(Employee aEmployee)
{
return dbConn.Update(aEmployee);
}
}
}
I would like to know :
1) Where is the place to create a database that can be used through out the app. This means I can use it anywhere in any page without recreating it each time I need to use it.
2) Will table be recreated each time in above code?
3) How to I do a select statement in any page ie CustomerPage.xaml or SalesPage.xaml ?
In WinRT, I used below code. How to do it in Xamarin forms? Do I need to recreate SQLite DB? How to get the Path?
Using (var db = new SQLite.SQLiteConnection(App.DBPath){
var query = db.query<CashReceivable>("select * from CashRcvdTbl where Cust='" + Id + "'";
foreach( var item in query)
{
}
}
1) Here,
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
This line in your ISQlite implementation points to your myDB.db3 SQLite file.
You can see this file into /data/data/#APP_PACKAGE_NAME#/files directory.
if (!File.Exists(path)) File.Create(path);
This line checks whether database file exists in above path or not. If not, then it creates this file once. This time it will be an empty sqlite file without any tables in it.
So, it will not recreated each time.
But, I think there is no need for this File exist check because, when you create a connection to the SQLite file, it automatically creates file if not exists.
So, it can be as simple as follows:
public class SqliteService : ISQLite
{
string dpPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), “myDB.db3”);
public SQLiteConnection GetConnection()
{
return new SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), dpPath, false);
}
}
2) Each time you create instance of DataAccess class, it will recreate Employee table/definition based on Table exists or not, as it calls dbConn.CreateTable<Employee>();
I generally write this line at Application Startup code.
public App ()
{
InitializeComponent ();
//Create all tables here. This will create them once when app launches.
using (var conn = DependencyService.Get<ISQLite>().GetConnection())
{
conn.CreateTable<Employee>();
}
MainPage = new HomePage ();
}
This will simply creates a new table in the SQLite file if table not exists, otherwise it updates the table definition.
3) You can do a select statement as follows:
public List<Employee> GetAllEmployees()
{
using (var conn = DependencyService.Get<ISQLite>().GetConnection())
{
return conn.Table<Employee>().ToList();
//OR
return conn.Query<Employee>("Select * From Employee");
}
}
In any page you can call this GetAllEmployees method to retrieve List of Employee.
I am developing an application, which requires chrome browser history. I have written a C# code for fetching the history. However there are two issues in my code which I am unable to figure out.
There is this warning.
Warning 1 There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "System.Data.SQLite", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. ChromeData
There is this error
SQLite error (5): database is locked
I tried closing the browser, but still there is this error. However, when I created a copy of History file and renamed it, gave its path instead of History, the program was working and it could read the file and fetch the data.
I am unable to figure it out where the error is. So, please help. I am posting my 3 class files.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.SQLite;
using System.Data;
namespace ChromeData
{
class GoogleChrome
{
public List<URL> Urls = new List<URL>();
public IEnumerable<URL> GetHistory()
{
string DocumentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
//Console.WriteLine(DocumentsFolder);
string[] tempstr = DocumentsFolder.Split('\\');
foreach(string s in tempstr)
{
Console.WriteLine(s);
}
string tempstr1 = "";
DocumentsFolder += "\\Google\\Chrome\\User Data\\Default";
if(tempstr[tempstr.Length-1] != "Local")
{
for(int i =0; i<tempstr.Length-1;i++)
{
tempstr1 += tempstr[i] + "\\";
}
DocumentsFolder = tempstr1 + "Local\\Google\\Chrome\\User Data\\Default";
}
Console.WriteLine(DocumentsFolder);
if(Directory.Exists(DocumentsFolder))
{
return ExtractUserHistory(DocumentsFolder);
}
return null;
}
public IEnumerable<URL> ExtractUserHistory(string folder)
{
DataTable HistoryData = ExtractFromTable("urls", folder);
foreach(DataRow row in HistoryData.Rows)
{
string url = row["url"].ToString();
string title = row["title"].ToString();
URL u = new URL(url.Replace('\'',' '), title.Replace('\'',' '), "Google Chrome");
Urls.Add(u);
}
return Urls;
}
DataTable ExtractFromTable(string table, string folder)
{
SQLiteConnection sql_con;
SQLiteDataAdapter DB;
SQLiteCommand sql_cmd;
string dbpath = folder + "\\History";
DataTable DT = new DataTable();
if(File.Exists(dbpath))
{
try
{
sql_con = new SQLiteConnection("Data Source=" + dbpath + ";Version=3;New=False;Compress=True;");
sql_con.Open();
sql_cmd = sql_con.CreateCommand();
string CommandText = "select * from " + table;
DB = new SQLiteDataAdapter(CommandText, sql_con);
DB.Fill(DT);
sql_con.Close();
}
catch(Exception e)
{
TextWriter errorWriter = Console.Error;
errorWriter.WriteLine(e.Message);
}
}
return DT;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ChromeData
{
class TestClass
{
public static List<URL> Urls = new List<URL>();
public static void Main()
{
string path = #"C:\Users\Public\Desktop\history.txt";
GoogleChrome g = new GoogleChrome();
Urls = (List<URL>)g.GetHistory();
using(StreamWriter sw = File.CreateText(path))
{
foreach(URL u in Urls)
{
sw.WriteLine(u.url);
}
}
Console.ReadLine();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChromeData
{
class URL
{
public string url;
public string title;
public string browser;
public URL(string url,string title,string browser)
{
this.browser = browser;
this.title = title;
this.url = url;
}
}
One solution is to copy the file to a temporary location and read it from there.
string source = #"C:\Users\{USERNAME}\AppData\Local\Google\Chrome\User Data\Default\History";
string target = #"C:\Temp\History";
if (File.Exists(target))
{
File.Delete(target);
}
File.Copy(source, target);
string cs = #"Data Source=" + target;
string sql = "Select * From urls";
using (SQLiteConnection c = new SQLiteConnection(cs))
{
c.Open();
using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr[1].ToString());
}
}
}
}
I've found chrome.exe will continue running, and holding the lock, despite exiting the browser as normal.
taskkill.exe /IM chrome.exe /F
This will shut down Chrome, with an added bonus of having a 'restore tabs' button upon restart by the user. Restore tabs is available because you killed forcefully.
It would be nice to be able to use BigQuery via ODBC. I already use MySQL through ODBC, and this would let me switch to BigQuery as a drop-in replacement for MySQL for my Big Data tables.
Simba, an expert in ODBC (they have ODBC drivers for nearly every data source you can think of), has built an ODBC connector for BigQuery. You can download it for free (for Windows) from the BigQuery third party tools page here (scroll down to the bottom of the page). If you would prefer to use Linux, you can download the ODBC driver from Simba directly from here. Note that Simba does charge if you download from their site. Their driver may be more up-to-date and will include support.
A feature to note is that the Simba driver has the ability to translate standard SQL-92 compliant SQL into BigQUery's dialect of SQL. This can be useful if you want to use it as a drop-in replacement for a relational database. However, if you want to use the full features of BigQuery (nested data, shuffled JOIN / GROUP BY), you should turn this switch off to send queries directly.
Once you've installed the BigQuery ODBC driver and created a DSN (see Simba ODBC docs for a step-by-step guide to DSN creation), you'll want to start making ODBC queries. Here is a code sample that does this from C#. If you compile and run it, it will connect to BigQuery, run a simple query, and print the results.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BigQueryE2E
{
/**
* Helper class to build an ODBC Connection to connect to a Simba
* BigQuery ODBC Driver.
*/
class ConnectionBuilder {
private String Dsn;
private String Catalog;
private String ExecCatalog;
private bool UseNativeQuery;
public ConnectionBuilder SetDsn(String dsn) {
Dsn = dsn;
return this;
}
public ConnectionBuilder SetCatalog(String catalog) {
Catalog = catalog;
return this;
}
public ConnectionBuilder SetBillingCatalog(String catalog) {
ExecCatalog = catalog;
return this;
}
public ConnectionBuilder SetUseNativeQuery(bool nativeQuery) {
UseNativeQuery = nativeQuery;
return this;
}
public OdbcConnection Build() {
if (Catalog == null || Dsn == null) {
throw new ArgumentException("Missing required Connection setting");
}
StringBuilder connectionString = new StringBuilder();
connectionString.AppendFormat("DSN={0}; Catalog={1};", Dsn, Catalog);
if (ExecCatalog != null) {
connectionString.AppendFormat("ExecCatalog={0};", ExecCatalog);
}
if (UseNativeQuery) {
connectionString.Append("UseNativeQuery=1");
}
OdbcConnection conn = new OdbcConnection();
conn.ConnectionString = connectionString.ToString();
return conn;
}
}
class Program {
private static String Query =
"SELECT corpus, SUM(word_count) " +
"FROM samples.shakespeare " +
"GROUP BY corpus";
private static void PrintResults(OdbcDataReader reader) {
for (int ii = 0; ii < reader.FieldCount; ii += 1) {
System.Console.Write("{0}{1}",
reader.GetName(ii),
ii + 1 < reader.FieldCount ? "\t" : "\n");
}
while (reader.Read()) {
for (int ii = 0; ii < reader.FieldCount; ii += 1) {
System.Console.Write("{0}{1}",
reader.GetValue(ii),
ii + 1 < reader.FieldCount ? "\t" : "\n");
}
}
}
static void Main(string[] args) {
OdbcConnection connection = new ConnectionBuilder()
.SetDsn("bigquery1")
.SetCatalog("publicdata")
.SetBillingCatalog("bigquery-e2e")
.Build();
try {
connection.Open();
using (OdbcCommand command = connection.CreateCommand()) {
command.CommandText = Query;
using (OdbcDataReader reader = command.ExecuteReader()) {
PrintResults(reader);
}
}
} catch (Exception ex) {
System.Console.WriteLine("Error {0}: {1}",
connection.State != ConnectionState.Open
? "opening connection" : "executing query",
ex);
} finally {
connection.Close();
}
System.Console.ReadKey();
}
}
}
in my asp.net application, i am calling a stored procedure (oracle) to get some values from database.
Following is the sp:
create or replace PROCEDURE GetUserData(
--SQLWAYS_EVAL# ARCHAR(100)
UserName IN NVARCHAR2, v_refcur OUT SYS_REFCURSOR)
as
BEGIN
BEGIN --SQLWAYS_EVAL# =#Password;
open v_refcur for SELECT StaffId,
UserName,
Password,
Pin,
LastUpdateId,
LastUpdateDate,
FullName,
PinFailedAttempts,
PinFailedDate
FROM UserData
WHERE UserName = UserName;
END;
RETURN;
END;
Can anyone help me how to call this sp from my asp.net code.
Using ODP, you'll can do something like the following:
make your stored procedure a function that takes the user name in parameter and returns a refcursor
create or replace FUNCTION GetUserData(UserName IN NVARCHAR2) RETURN SYS_REFCURSOR;
and then
using (var connection = new OracleConnection(connectionString))
{
using (var command = new OracleCommand("GetUserData", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.BindByName = true;
// Return value parameter has to be added first !
var returnValueParameter = new OracleParameter();
returnValueParameter.Direction = ParameterDirection.ReturnValue;
returnValueParameter.OracleDbType = ParameterDirection.RefCursor;
command.Parameters.Add(returnValueParameter);
var userNameParameter = command.Parameters.Add("UserName", userName);
returnValueParameter.Direction = ParameterDirection.In;
using (OracleDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Read the current record's fields
}
}
}
}
The Microsoft Enterprise Library simplifies the discovery and binding of Oracle Stored Procedures. It is not too difficult to build a Data Access Layer between your Business Objects and the Oracle database. I am more a fan of ORM tools these days like DevExpress's XPO, which in the latest release supports calling stored procedures. However, the Microsoft Entlib is free whereas DevExpress is not.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Your.BusinessObjects;
namespace DataAccess
{
public class UserDataDAL
{
public static Database dataBase = DatabaseFactory.CreateDatabase(); ///< Use default connection string configured in web.config
public static List<UserInfo> GetData(string userName)
{
List<UserInfo> listOfUserInfo = new List<UserInfo>();
UserInfo userInfo;
DbCommand cmd = dataBase.GetStoredProcCommand("SCHEMA.GETUSERDATA");
dataBase.DiscoverParameters(cmd);
dataBase.SetParameterValue(cmd, "USERNAME", userName);
using (IDataReader dr = dataBase.ExecuteReader(cmd))
{
while (dr.Read())
{
userInfo = new UserInfo();
userInfo.StaffId = dr["STAFFID"] != DBNull.Value ? Convert.ToInt32(dr["STAFFID"]) : 0;
userInfo.UserName = dr["USERNAME"] != DBNull.Value ? Convert.ToString(dr["USERNAME"]) : String.Empty;
userInfo.Password = dr["PASSWORD"] != DBNull.Value ? Convert.ToString(dr["PASSWORD"]) : String.Empty;
userInfo.LastUpdateId = Convert.ToInt32(dr["LASTUPDATEID"]);
userInfo.LastUpdateDate = dr["LASTUPDATEDATE"] != null ? Convert.ToDateTime(dr["LASTUPDATEDATE"]) : new DateTime();
listOfUserInfo.Add(userInfo);
}
}
return listOfUserInfo;
}
}
}
If you only ever expect one row to be returned from the procedure, then you can return the first item in the list if present etc.