Get path of sqlite database file - c#

Hi everyone i can't set a relative path to open my database, the project is structured in this mood
projectname
db/acces.db
info/try.cs
This is the code inside try.cs with which i should open the database, obviously if I put the full path it goes:
try {
using (SQLiteConnection conn = new SQLiteConnection(#"data source="db/access.db")
{
conn.Open();
using (SQLiteCommand fmd = conn.CreateCommand()){
fmd.CommandText = #"SELECT * FROM 'test';
fmd.CommandType = CommandType.Text;
SQLiteDataReader r = fmd.ExecuteReader();
while (r.Read())
Debug.Writeline("foo");
conn.Close();
}
}
catch (Exception e){
Debug.WriteLine("Errors");
}
I should take the path of the acces.db file, not complete but relative to my project, to be set in data source, how should i do?

You can use something like this:
using System.IO;
var connection = "Data Source=" + Path.Combine(Directory.GetCurrentDirectory(), "db\\access.db")
try {
using (SQLiteConnection conn = new SQLiteConnection(connection)
{
conn.Open();
using (SQLiteCommand fmd = conn.CreateCommand()){
fmd.CommandText = #"SELECT * FROM 'test';
fmd.CommandType = CommandType.Text;
SQLiteDataReader r = fmd.ExecuteReader();
while (r.Read())
Debug.Writeline("foo");
conn.Close();
}
}
catch (Exception e){
Debug.WriteLine("Errors");
}

You said you should get something of type Data Source=C:\\Users\\mypc\\Documents\\tesrepo\\Myapp\\testApp\\db\\test.db.
Here is how to get the correct path.
Project path:
Directory.GetParent(workingDirectory).Parent.FullName;
Add the path you want at the end: For example, the address of the 123.mp3 file in the music folder here is:
string filepath = Path.Combine(projectDirectory + "\\music\\123.mp3");
//Get db address
string workingDirectory = Environment.CurrentDirectory;
string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;
string dbpath = Path.Combine(projectDirectory + "\\db\\test.db");
dbpath is what you want.
If you have any questions about my code, please add a comment below.
Updated:
You can import the updated file into the output directory through this operation.
Your path would work without any modification.

Related

Error comparing between 2 Datatables in C#

I am facing the following problem:
I select an arbitrary number of directories, and the files within them should be inserted into 2 SQL tables. There is the initial state in which they are read and the current state, which is updated every 5 minutes and written to the second table. These states are compared, and if a file is deleted, added, or modified, the program should output an error message. The error message works perfectly for deleted or added files, but if I rename a file, it is always moved to the last position when reading into the table, and the program then gives me an error message for multiple files, not just the one whose name was changed (changing the file size does not produce this error). Although I have a workaround, it then becomes impossible for me to select multiple directories. I'm not entirely sure which part of the code is still needed besides what I'm posting here to help me, so it would be nice if you could point me in the right direction! I have searched through Stack Overflow, checked out YouTube tutorials, tried ChatGPT, and asked the few programmers I know, but no one could help me. I hope I finally find a solution to my problem
The process of reading into the table looks like this:
if (result == DialogResult.OK)
{
string[] dirsArray = Directory.GetDirectories(fbd.SelectedPath, "*", SearchOption.AllDirectories);
string[] filesArray = Directory.GetFiles(fbd.SelectedPath, "*.*", SearchOption.AllDirectories);
foreach (string dir in dirsArray)
{
if (!dirs.Contains(dir))
{
dirs.Add(dir);
}
}
foreach (string file in filesArray)
{
if (!files.Contains(file))
{
files.Add(file);
}
}
using (SqlConnection connection = new SqlConnection("conn string of database"))
{
connection.Open();
SqlCommand com = new SqlCommand();
com.Connection = connection;
com.CommandText = "DELETE FROM second table";
SqlDataReader data = com.ExecuteReader();
connection.Close();
connection.Open();
SqlCommand com1 = new SqlCommand();
com1.Connection = connection;
com1.CommandText = "DBCC CHECKIDENT ('datatable2', RESEED, 1)";
com1.ExecuteNonQuery();
connection.Close();
connection.Open();
foreach (string item1 in files)
{
if (!System.IO.File.Exists(item1))
{
continue;
}
string fileName = System.IO.Path.GetFileName(item1);
string filePath = System.IO.Path.GetDirectoryName(item1);
DateTime fileDate = System.IO.File.GetCreationTime(item1.ToString());
long fileSize = new System.IO.FileInfo(item1.ToString()).Length;
string allData = fileName + fileSize.ToString() + filePath + fileDate.ToString();
var fileHash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(allData.ToString()));
using (SqlCommand cmd1 = new SqlCommand("INSERT INTO second table (E_Path, E_Filename, E_Date, E_Size, E_Hash) VALUES (#filePath, #fileName, #fileDate, #fileSize, #fileHash)", connection))
{
cmd1.Parameters.AddWithValue("#fileName", fileName);
cmd1.Parameters.AddWithValue("#filePath", filePath);
cmd1.Parameters.AddWithValue("#fileDate", fileDate);
cmd1.Parameters.AddWithValue("#fileSize", fileSize);
cmd1.Parameters.AddWithValue("#fileHash", fileHash);
cmd1.ExecuteNonQuery();
}
}
SqlDataAdapter myCommand;
string select = "SELECT * second Table";
myCommand = new SqlDataAdapter(select, connection);
var builder = new SqlCommandBuilder(myCommand);
var myDataSet = new DataSet();
myCommand.Fill(myDataSet);
DataBaseTemp.DataSource = myDataSet.Tables[0];
}

Programmatically Backup database from host in asp.net

I have a website and an SQL Server database on it. The control panel of my host is Plesk 12.5. Now, I want backup my database and store it on a special folder in my host. I've added permisson to save data to this special folder in my host control panel, and the function that I use it to create and save database backup is :
string CS = "server=localhost;database = Test;uid=***; password=***;";
string filename = "testDB.bak";
string folderPath = Server.MapPath("~/Backups/");
if (!Directory.Exists(folderPath))
Directory.CreateDirectory(folderPath);
using (SqlConnection con = new SqlConnection(CS))
{
string SqlStmt = String.Format("Backup Database Test To Disk = '{0}'", folderPath + filename);
using (SqlCommand cm = new SqlCommand(SqlStmt, con))
{
try
{
con.Open();
cm.ExecuteNonQuery();
con.Close();
}
catch (Exception E)
{
Label1.Text = E.Message;
return;
}
}
}
'Backups' folder is created, but for backup, get this error: "Cannot open backup device 'C:***********.com\httpdocs\Backups\testDB.bak'. Operating system error 5(Access is denied.). BACKUP DATABASE is terminating abnormally."

set default image path

how do i set a default image when the image file was not found or not exist ?
the error i got was
because file with name 8813.jgp was not exist. and i want to set it default as 1.jpg. how do i check if its exist or not.
iam using this code
public void profilepicture()
{
DataTable dtprofile = new DataTable();
DataSet dsprofile = new DataSet();
string path;
SqlCommand command = new SqlCommand();
SqlDataAdapter adapter = new SqlDataAdapter();
try
{
dsprofile.Clear();
dtprofile.Clear();
command.Connection = myConnection;
command.CommandText = "//some query//'";
myConnection.Open();
adapter.SelectCommand = command;
adapter.Fill(dtprofile);
adapter.Fill(dsprofile);
}
catch (Exception ex)
{
MessageBox.Show("error" + ex);
myConnection.Close();
}
path = dsprofile.Tables[0].Rows[0][0].ToString() + "\\" + number + ".jpg";
pictureEdit2.Image = Image.FromFile(path);
myConnection.Close();
}
You can check to see if the file exists using File.Exists() in the System.IO namespace.
https://msdn.microsoft.com/en-us/library/system.io.file.exists(v=vs.110).aspx
if(File.Exists("filePath"))
{
// Load file.
}
else
{
// Load default file.
}
Its quite trivial actually!
path = dsprofile.Tables[0].Rows[0][0].ToString() + "\\" + number + ".jpg";
if(File.Exists(path)){
pictureEdit2.Image = Image.FromFile(path);
}
else
{
pictureEdit2.Image = Image.FromFile("NotFound.jpg");
}
I suggest you to create a separate method to get the SQL Table, so you can use it in every method you need and then you create a different method for the profile picture using the code as below:
public DataTable GetSqlTable(string query)
{
using (SqlConnection dbConnection = new SqlConnection(#"Data Source={ServerName};Initial Catalog={DB_Name};UID={UserID}; Password={PWD}"))
{
dbConnection.Open();
SqlDataAdapter da = new SqlDataAdapter(query, dbConnection);
da.SelectCommand.CommandTimeout = 600000; //optional
try
{
DataTable dt = new DataTable();
da.Fill(dt);
da.Update(dt);
dbConnection.Close();
return dt;
}
catch
{
dbConnection.Close();
return null;
}
}
}
public void profilepicture()
{
DataTable dt = GetSqlTable("/* some query */");
string number = "some value";
string defaultImg = "defaultImgPath";
if(dt.Rows.Count > 0)
{
string path = dt.Rows[0][0].ToString() + "\\" + number + ".jpg";
pictureEdit2.Image = Image.FromFile(File.Exists(path) ? path : defaultImg);
}
else
{
pictureEdit2.Image = Image.FromFile(defaultImg);
}
}
Sorry for my English
Standalone applications
If your application is a standalone application (requires only exe and no other files in hard disk), you can add the default image in a resource file and use it as required. Following stack overflow link explains how to access images added into a resource file Load image from resources area of project in C#
pictureEdit2.Image = File.Exists(path) ? Image.FromFile(path) : Resources.myImage;
Installed applications
If your application is not a standalone application, you can use Environment.GetFolderPath method or Application.StartupPath to store the default image.
To avoid file not found exception, you may need to use File.Exists in your code something like below
string defaultImagePath = Application.StartupPath + "\\1.jpg";
pictureEdit2.Image = Image.FromFile( File.Exists(path) ? path : defaultImagePath) ;

Record inserted successfully but database not updated C# and SQL Server Compact Database

private void button1_Click(object sender, EventArgs e)
{
string usernames = textBox1.Text;
string passwords = textBox2.Text;
string emailid = textBox5.Text;
string telno = textBox6.Text;
string connectionstring = "Data Source=|DataDirectory|\\libdb.sdf; Persist Security Info=False ;";
using (SqlCeConnection con = new SqlCeConnection(connectionstring))
{
con.Open();
using (SqlCeCommand Query = new SqlCeCommand("INSERT INTO Registers " + "(usernames,passwords,emailid,telno) " + "VALUES (#usernames,#passwords,#emailid,#telno)", con))
{
Query.Parameters.AddWithValue("#usernames", usernames);
Query.Parameters.AddWithValue("#passwords", passwords);
Query.Parameters.AddWithValue("#emailid", emailid);
Query.Parameters.AddWithValue("#telno", telno);
Query.ExecuteNonQuery();
}
MessageBox.Show("QueryExecuted");
con.Close();
MessageBox.Show("Closedconnecrion");
con.Dispose();
MessageBox.Show("disposed");
this.Close();
/*string conString = "Data Source=" +
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"MyAppData\\database.sdf") + ";Password=yourPassword;";
even this method dosent works */
}
}
}
on executing this code I find it executes successfully. But when I go and check the database, I find the entries empty...
I even tried refreshing database..
I didn't find problem in connectivity.
Query no error executed successfully.
The problem is I didn't find result or the data I gave as input in database.
Please be descriptive with code eg and mail to scarlet.gabriel#gmail.com
Test your connection with the database first, You can get the connection string by creating the udl file.
create a textfile and savaas it with the extension udl (example connection.udl).
double click and run this file.
a window will be opened where you can get the option for getting the connection string.
after testing the connection, close this window and open this file with a note pad.
copy the connection string and paste it in the below statement.
string connectionstring =" paste here";
How can you be sure if the connection is open and has done the job? Use try... catch block to catch if any error occurs:
using (SqlCeConnection con = new SqlCeConnection(connectionstring))
{
try{con.Open();}
catch(Exception ex)
{
// database connection error. log/display ex. > return.
}
if(con.State==ConnectionState.Open)
{
using (SqlCeCommand Query = new SqlCeCommand("INSERT INTO Registers " + "(usernames,passwords,emailid,telno) " + "VALUES (#usernames,#passwords,#emailid,#telno)", con))
{
Query.Parameters.AddWithValue("#usernames", usernames);
Query.Parameters.AddWithValue("#passwords", passwords);
Query.Parameters.AddWithValue("#emailid", emailid);
Query.Parameters.AddWithValue("#telno", telno);
try{
Query.ExecuteNonQuery();
}
catch(Exception ex)
{
// database communication error. log/display ex
}
}
MessageBox.Show("QueryExecuted");
}
if(con.State==ConnectionState.Open)
{
try{con.Close();}
catch{}
}
}
Instead of using connectionstring = "Data Source=|DataDirectory|\libdb.sdf; Persist Security Info=False ;"; Please try to use absolute path like
connectionstring = "Data Source=C:\Users\chandra\Documents\Visual Studio 2010\Projects\Window\LMS\AppData\LMSDatabase.sdf;Persist Security Info=False;";
I hope this will work.
Thanks

How to Open a CSV or XLS with Jet OLEDB and attain Table Lock?

I am trying to figure out how to read/write lock a CSV or XLS file when I read it as a Database via Jet OLEDB.
The following code will open a CSV as a DB and load it into a DataTable object:
private DataTable OpenCSVasDB(string fullFileName)
{
string file = Path.GetFileName(fullFileName);
string dir = Path.GetDirectoryName(fullFileName);
string cStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\";";
string sqlStr = "SELECT * FROM [" + file + "]";
OleDbDataAdapter da;
DataTable dt = new DataTable();
try
{
da = new OleDbDataAdapter(sqlStr, cStr);
da.Fill(dt);
}
catch { dt = null; }
}
What I want to make sure of is that while I have the CSV or XLS file open, that I have a Read/Write LOCK on the Table (aka. the file), so that any other application that comes along and tries to read/write to this file has to wait its turn.
Does this happen automatically? If not, what do I need to do to make sure this does happen?
Btw, I'm working in C#/.NET 2.0, if that makes any difference...
Update: So, I'm clarifying my requirements now:
XLS file (because I need SELECT and UPDATE functionality) [CSV can only SELECT and INSERT]
LOCK the XLS file while the DB is Open. (can't have multiple threads and/or processes stepping on each other's changes...)
Read into DataTable object (for ease of working)
OLEDB's Jet driver locks flat files while there's an open OleDbDataReader to them. To verify this, look at the VerifyFileLockedByOleDB method in the code sample below. Note that having an open OleDbConnection is not enough-- you have to have an open Reader.
That said, your code posted above does not keep an open connection, since it uses OleDbDataAdapter.Fill() to quickly connect to the data source, suck out all the data, and then disconnect. The reader is never left open. The file is only locked for the (short) time that Fill() is running.
Furthermore, even if you open the reader yourself and pass it into DataTable.Load(), that method will close your DataReader for you once it's done, meaning that the file gets unlocked.
So if you really want to keep the file locked and still use a DataTable, you'll need to manually populate the datatable (schema and rows!) from an IDataReader, instead of relying on DataAdapter.Fill() or DataTable.Load().
Anyway, here's a code sample which shows:
your original code
an example which won't work because DataTable.Load() will close the DataReader and unlock the file
an alternate approach which will keep the file locked while you're working with the data, via operating at the row level using DataReader rather than using a DataTable
UPDATE: looks like keeping a DataReader open will prevent the same process from opening the file, but another process (e.g. Excel) can open (and write to!) the file. Go figure. Anyway, at this point I'd suggest, if you really want to keep the file locked, consider using something else besides OLEDB where you have more fine-grained control over how (adn when!) the file is opened and closed. I'd suggest the CSV reader fromhttp://www.codeproject.com/KB/database/CsvReader.aspx, which is well-tested and fast, but will give you the source code so if you need to change file-locking/opening/closing, you can do so.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
using System.IO;
namespace TextFileLocking
{
class Program
{
private static DataTable OpenCSVasDB(string fullFileName)
{
string file = Path.GetFileName(fullFileName);
string dir = Path.GetDirectoryName(fullFileName);
string cStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\";";
string sqlStr = "SELECT * FROM [" + file + "]";
OleDbDataAdapter da;
DataTable dt = new DataTable();
try
{
da = new OleDbDataAdapter(sqlStr, cStr);
da.Fill(dt);
}
catch { dt = null; }
return dt;
}
private static DataTable OpenCSVasDBWithLockWontWork(string fullFileName, out OleDbDataReader reader)
{
string file = Path.GetFileName(fullFileName);
string dir = Path.GetDirectoryName(fullFileName);
string cStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\";";
string sqlStr = "SELECT * FROM [" + file + "]";
OleDbConnection openConnection = new OleDbConnection(cStr);
reader = null;
DataTable dt = new DataTable();
try
{
openConnection.Open();
OleDbCommand cmd = new OleDbCommand(sqlStr, openConnection);
reader = cmd.ExecuteReader();
dt.Load (reader); // this will close the reader and unlock the file!
return dt;
}
catch
{
return null;
}
}
private static void OpenCSVasDBWithLock(string fullFileName, Action<IDataReader> dataRowProcessor)
{
string file = Path.GetFileName(fullFileName);
string dir = Path.GetDirectoryName(fullFileName);
string cStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\";";
string sqlStr = "SELECT * FROM [" + file + "]";
using (OleDbConnection conn = new OleDbConnection(cStr))
{
OleDbCommand cmd = new OleDbCommand(sqlStr, conn);
conn.Open();
using (OleDbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
dataRowProcessor(reader);
}
}
}
}
private static void VerifyFileLockedByOleDB(string fullFileName)
{
string file = Path.GetFileName(fullFileName);
string dir = Path.GetDirectoryName(fullFileName);
string cStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\";";
string sqlStr = "SELECT * FROM [" + file + "]";
using (OleDbConnection conn = new OleDbConnection(cStr))
{
OleDbCommand cmd = new OleDbCommand(sqlStr, conn);
conn.Open();
using (OleDbDataReader reader = cmd.ExecuteReader())
{
File.OpenRead(fullFileName); // should throw an exception
while (reader.Read())
{
File.OpenRead(fullFileName); // should throw an exception
StringBuilder b = new StringBuilder();
for (int i = 0; i < reader.FieldCount; i++)
{
b.Append(reader.GetValue(i));
b.Append(",");
}
string line = b.ToString().Substring(0, b.Length - 1);
Console.WriteLine(line);
}
}
}
}
static void Main(string[] args)
{
string filename = Directory.GetCurrentDirectory() + "\\SomeText.CSV";
try
{
VerifyFileLockedByOleDB(filename);
}
catch { } // ignore exception due to locked file
OpenCSVasDBWithLock(filename, delegate(IDataReader row)
{
StringBuilder b = new StringBuilder();
for (int i = 0; i <row.FieldCount; i++)
{
b.Append(row[i].ToString());
b.Append(",");
}
string line = b.ToString().Substring(0, b.Length - 1);
Console.WriteLine(line);
});
}
}
}
UPDATE: The following does not appear to lock my DB as I had hoped...
After much more digging, I found this page:
ADO Provider Properties and Settings
It says:
Jet OLEDB:Database Locking Mode
A Long value (read/write) that
specifies the mode used when locking
the database to read or modify
records.
The Jet OLEDB:Database Locking Mode
property can be set to any of the
following values:
Page-level Locking 0
Row-level Locking 1
Note A database can only be open in
one mode at a time. The first user to
open the database determines the
locking mode to be used while the
database is open.
So I assume that my code would get changed to:
string cStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\";"
+ "Jet OLEDB:Database Locking Mode=0";
Which should give me Page-level locking. If I wanted Row-level locking, I'd switch the value to 1.
Unfortunately, this doesn't actually appear to do any table/row/page locking when opening a CSV file as a DB.
Ok, so that new function you wrote kinda works, but I still end up with a "Race condition" which then causes an exception to be thrown. So in this section of the code:
using (OleDbConnection conn = new OleDbConnection(cStr))
{
OleDbCommand cmd = new OleDbCommand(sqlStr, conn);
conn.Open();
using (OleDbDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
reader.GetString(0); // breakpoint here
}
}
}
I put a breakpoint on the line with the comment "breakpoint here" and then ran the program. I then located the CSV file in File Explorer and tried to open it with Excel. It causes Excel to wait for the file to be unlocked, which is good.
But here's the bad part. When I clear the breakpoint and then tell it to continue debugging, Excel sneaks in, grabs a lock on the file and causes an exception in my running code.
(The exception is: The Microsoft Jet database engine cannot open the file ''. It is already opened exclusively by another user, or you need permission to view its data.)
I guess I can always wrap that code in a try-catch block, but when the exception occurs, I won't know if it is a legitimate exception or one caused by this weird condition.
The exception seems to occur when the Reader is finished reading. (after it reads the last row, but still is in the "using (OleDbDataReader reader = cmd.ExecuteReader())" loop.

Categories

Resources