FluentMigrator create password protected SqlLite DB - sqlite

I use FluentMigrator to create a SqlLite DB in C# using FluentMigrator.Runner.MigrationRunner. I wonder is there any way to use the SetPassword command o the SqlConnection only when the DB needs to be created ? There's a SqLiteRunnerContextFactory object but it don't seem to be a property that I can use to specify password.
public MigrationRunner CreateMigrationRunner(string connectionString, string[] migrationTargets, Assembly assembly, long version)
{
var announcer = new TextWriterAnnouncer(Console.WriteLine) { ShowSql = true };
var options = new ProcessorOptions { PreviewOnly = false, Timeout = 60 };
var runnerContext = new SqLiteRunnerContextFactory().CreateRunnerContext(connectionString, migrationTargets, version, announcer);
var sqlLiteConnection = new SQLiteConnection(connectionString);
//If the DB has already been created, it crashes later on if I specify this
sqlLiteConnection.SetPassword("ban4an4");
return new MigrationRunner(assembly,
runnerContext,
new SQLiteProcessor(sqlLiteConnection,
new SQLiteGenerator(),
announcer,
options,
new SQLiteDbFactory()));
}
I would like to avoid having to look if the file exists before setting password on connection.

Well, finally the code below works perfectly by using SetPassword everytime you create de runner. No need to check if the file exists or not. First time it creates it with the password and second time it opens it with it seems to use it to open DB. Which is exactly what I was looking for.

Related

Embedding a readonly SQLite Database in a DLL and conenct via Entity Framework

I have a requirement that my DLL should have a readonly database. I made my database as a embedded resource but i am not able to figure it out to connect to the database via entity framework.
try
{
var dataSet = ConfigurationManager.GetSection("system.data") as System.Data.DataSet;
dataSet.Tables[0].Rows.Add("SQLite Data Provider"
, ".Net Framework Data Provider for SQLite"
, "System.Data.SQLite"
, "System.Data.SQLite.SQLiteFactory, System.Data.SQLite");
}
catch (System.Data.ConstraintException) { }
string providerName = "System.Data.SQLite";
string serverName = "NameSpace.DB.sqlite";
// Initialize the connection string builder for the
// underlying provider.
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
// Set the properties for the data source.
sqlBuilder.DataSource = serverName;
sqlBuilder.InitialCatalog = "DB.sqlite";
sqlBuilder.IntegratedSecurity = true;
// Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString();
// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder =
new EntityConnectionStringBuilder();
//Set the provider name.
entityBuilder.Provider = providerName;
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = providerString;
// Set the Metadata location.
entityBuilder.Metadata = #"res://*/DataModel.DB.csdl|
res://*/DataModel.DB.ssdl|
res://*/DataModel.DB.msl";
Console.WriteLine(entityBuilder.ToString());
using (EntityConnection conn =
new EntityConnection(entityBuilder.ToString()))
{
conn.Open();
Console.WriteLine("Just testing the connection.");
_container = new MyEntities(conn);
var usersList = _container.UserTable.ToList();
}
It works only when we are copying the database to the client application. I don't want to provide the database as a separate file. I want to embedded it in the dll and give only the dll to other applications.
Regards,
Vivek
As CL. said SQLite has to be in an independent .sqlite file, It cannot be embedded. Take a look at SQL Server Compact. It is all you need, an embedded SQL Database that you can access using Entity Framework.
Here's a tutorial in how to connect to EF.
SQLite databases are based on files.
The SQLite library has the ability to access files through a virtual file system, which would allow redirecting file accessing to somewhere else. So it would be possible to implement a VFS that accesses a resource.
However, System.Data.SQLite does not appear to allow registering your own VFS.

Need to setup SqlDependency per-user

System Scope
I have a database with a lot of users (over 50,000). At any time there may be 100-200 people logged in and actively using the system. The system is ASP.NET MVC 4, with Sql Server 2008 backend. For data access we are using Dapper.
Requirements
I am trying to build a notification component that has the following attributes:
When a new record is created in the [dbo.Assignment] table (with OwnerId = [Currently logged in user]), I need to update the Cache inside of an asp.net application.
I don't want to receive any notifications for users who are not actively online, as this would be a massive waste of resources)
Specific Questions:
Should I be using SqlDependency, SqlCacheDependency, or SqlNotification?
Assuming that we are using SqlDependency, how would I remove the Dependency.OnChange handler when user has logged out.
Any code samples would be much appreciated, as this has consumed the whole part of my day trying to figure it out.
Here is the current code
public IList<Notification> GetNotifications(string userName)
{
Cache o = HttpContext.Current.Cache;
if (o["Notifications_" + userName] == null)
{
var notifications = new List<Notification>();
using (var cn = new SqlConnection(getSQLString()))
{
using (var cmd = cn.CreateCommand())
{
var parameter = new SqlParameter("Employee_Cd", SqlDbType.Char, 30) { Value = userName };
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Notifications.Assignments";
cmd.Parameters.Add(parameter);
cmd.Notification = null;
var dependency = new SqlCacheDependency(cmd);
cn.Open();
using (var dr = cmd.ExecuteReader())
{
// this is where you build your cache
while (dr.Read())
{
var obj = new Notification();
obj.Name = dr["Name"].ToString();
notifications.Add(obj);
}
dr.Close();
}
HttpContext.Current.Cache.Insert("Notifications_" + userName,
notifications,
dependency,
DateTime.Now.AddDays(1D),
Cache.NoSlidingExpiration);
}
}
}
return (List<Notification>) o["Notifications_" + userName];
}
Note: I am not experienced with using SqlDependencies, as I have never really needed to use them until today. It's very possible that I am overlooking something important.
I didn’t really use any of these techniques but here are some alternatives that you can create yourself that will do the job just as good.
If you need to update cache every time new record is inserted into dbo.Assignment table why not create OnInserted event in your data access layer that will notify the cache object to refresh?
Another thing you can to is to create INSERT trigger in Assignemt table and another table that can look like this dbo.Cache (LastUpdate datetime). Trigger will insert value into Cache table and your application cache can ping this table like every X mins or X seconds to see if cache update is required.
If you need to refresh the cache immediately after record is inserted triggers might be an overkill because you’d have to ping Cache table probably every second but if you have 200 online users at a time that probably won’t make much of a difference in DB performance.
There is a lot of work if you want to implement these for a lot of tables but since this is only one table this might turn out to be faster way than implementing built in cache mechanisms.

MySQL Data Access Layer: How do you store your queries?

I've been building this project as the solo dev for a while, and while I'm comfortable in the front end and middle tier, I don't really think I'm doing the database the way I should be, and the reason why is because I simply don't really know of any other way. The way I'm currently getting data is by testing out queries in my MySQL workbench and copying and pasting the SQL as a string literal into a method that makes a call to the DB, pulls the data and hydrates my objects.
This hasn't really been a problem until recently, when I had to create a monster of a query and it got me thinking that maybe there's a better way to do this. I don't have a formal DAL separated out, so I know there's room for improvement there, but I was curious about what the correct way would be to store SQL strings. I assume there is a tool somewhere built into VS10 where I can manipulate and work with SQL as SQL instead of as a string.
You should be doing this in stored procedures. That will basically format and store your query. You set parameters that are passed in from your code, then read out the results.
Example:
The C# method:
private void SetNote()
{
const string sql = "sp_SelectControllerNoteByID";
using (var conn = MocSystem.GetMocDbConnection())
{
using (var comm = new SqlCommand(sql, conn))
{
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add(new SqlParameter("#ControllerNoteID", ControllerNoteId));
try
{
conn.Open();
using (var rdr = comm.ExecuteReader())
{
while (rdr.Read())
{
CommentText = rdr["NoteText"].ToString();
_commentor = new User(new Guid(rdr["NoteAuthor"].ToString()));
CommentDate = (DateTime)rdr["NoteDate"];
MocRequestId = (int)rdr["MocRequestID"];
}
}
}
catch (Exception ex)
{
HasError = true;
ErrorMessage += "\nThere was a problem building the note: " + ex.Message;
}
}
}
}
The stored procedure on the DBMS (sql server in this example):
ALTER proc [dbo].[sp_SelectControllerNoteByID]
#ControllerNoteID int
AS
SELECT
ControllerNoteID,
NoteText,
NoteDate,
NoteAuthor,
MocRequestID
FROM
ControllerNotes
WHERE
ControllerNoteID = #ControllerNoteID
So here we call the stored procedure which in this case is just a simple select statement, then we read it out into an object via ADO. Now, this way, you can modify your query without recompiling. Unless you add parameters, in which case you'll have to update those in your code as well.

"Unable to open database file" using SQLite on Windows Phone 7

I am using SQLite for Windows Phone 7 (http://sqlitewindowsphone.codeplex.com/) and I have done every steps from this tutorial (http://dotnetslackers.com/articles/silverlight/Windows-Phone-7-Native-Database-Programming-via-Sqlite-Client-for-Windows-Phone.aspx)
Then I try to make some simple application with basic features like select and delete. App is working properly till I want to make one of this operations. After I click select or delete, compiler shows me errors that he is unable to open database file...
I have no idea why?
I used the same Sqlite client, and had the same problem. This problem occurs because the sqlite try to create file in IsolatedFileStorage "DatabaseName.sqlite-journal" and it does not have enough permissions for that. I solved the problem, so that created "DatabaseName.sqlite-journal" before copying database to IsolatedFileStorage. Here's my method that did it:
private void CopyFromContentToStorage(String assemblyName, String dbName)
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string uri = dbName + "-journal";
store.CreateFile(uri);
using (Stream input = Application.GetResourceStream(new Uri("/" + assemblyName + ";component/" + dbName,UriKind.Relative)).Stream)
{
IsolatedStorageFileStream dest = new IsolatedStorageFileStream(dbName, FileMode.OpenOrCreate, FileAccess.Write, store);
input.Position = 0;
CopyStream(input, dest);
dest.Flush();
dest.Close();
dest.Dispose();
}
}
it helped me, and worked well.
hope this will help you
Are you sure the file exists?
You can check like that:
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
exists = store.FileExists(DbfileName);
}

Oracle query fired off, then never returns

I have this problem in my ASP.NET application where I'm seeing some of my Oracle queries fired off to the server then not returning. Ever. It happens in several places in my app and I can't explain it. Here's one specific scenario where I'm seeing this behavior:
During application start-up I am pre-fetching data asynchronously into the application state (the choice was made to use app state instead of cache b/c the data never changes during the lifetime of the app).
Action<string, object> AddApplicationState = (string name, object data) =>
{
Application.Lock();
Application.Add(name, data);
Application.UnLock();
};
Func<DataTable> GetFullNames = () => Database.GetAllNames();
Func<DataTable> GetProvinceNames = () => Database.GetProvinceNames();
Func<DataTable> GetTribeNames = () => Database.GetTribeNames();
GetFullNames.BeginInvoke(result => AddApplicationState("AllNames", GetFullNames.EndInvoke(result)), null);
GetProvinceNames.BeginInvoke(result => AddApplicationState("ProvinceNames", GetProvinceNames.EndInvoke(result)), null);
GetTribeNames.BeginInvoke(result => AddApplicationState("TribeNames", GetTribeNames.EndInvoke(result)), null);
The second two return just fine, but the first either never returns or returns after about 10 minutes. After firing up Oracle SQL Developer I go to the 'monitor sessions' tool and can see a single session for the query. It looks like it has completed, b/c the wait time is (null) and the session is inactive. Here's the ADO.NET code used to query the database:
public static DataTable GetAllNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
var sql = new StringBuilder();
sql.AppendLine("SELECT NAME_ID, NATIVE_NAME, NVL(FREQUENCY,0) \"FREQUENCY\", CULTURE_ID,");
sql.AppendLine("ENGLISH_NAME, REGEXP_REPLACE(ENGLISH_NAME, '[^A-Za-z]', null) \"ENGLISH_NAME_STRIPPED\"");
sql.AppendLine("FROM NAMES");
oracmd.CommandText = sql.ToString();
var orada = new OracleDataAdapter(oracmd);
var dtAllNames = new DataTable();
orada.Fill(dtAllNames);
return dtAllNames;
}
}
}
public static DataTable GetTribeNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
var sql = new StringBuilder();
sql.AppendLine("SELECT DISTINCT NAME_ID, English_Name \"TRIBE_NAME_ENGLISH\",");
sql.AppendLine("REGEXP_REPLACE(English_Name, '[^A-Za-z]',null) \"TRIBE_ENGLISH_NAME_STRIPPED\",");
sql.AppendLine("NATIVE_NAME \"TRIBE_NATIVE_NAME\"");
sql.AppendLine("FROM NAMES");
sql.AppendLine("WHERE NAME_ID IN ");
sql.AppendLine("(SELECT NAME_ID_TRIBE FROM TRIBES UNION SELECT NAME_ID_FAMILY FROM TRIBES)");
sql.AppendLine("ORDER BY English_Name");
oracmd.CommandText = sql.ToString();
var orada = new OracleDataAdapter(oracmd);
var dt = new DataTable();
orada.Fill(dt);
return dt;
}
}
}
public static DataTable GetProvinceNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
oracmd.CommandText = "SELECT DISTINCT PROVINCE_ID, PROVINCE_NAME_NATIVE, PROVINCE_NAME_ENGLISH FROM PROVINCES";
var orada = new OracleDataAdapter(oracmd);
var dtRC = new DataTable();
orada.Fill(dtRC);
return dtRC;
}
}
}
As you can see, the ADO.NET code is pretty standard (and boring!) stuff. When run in SQL Developer, the queries return less than a second. The first query returns x rows, the second x rows, and the third x rows. But this problem of queries being fired off then never returning happens often and I can't seem to track down the issue. Anyone have any thoughts?
And finally, since I realize it could be something completely unrelated to code, I am running the app locally (from Visual Studio) on a Windows XP SP3 machine and connecting via VPN to a remote Oracle 10g Enterprise instance running on Windows 2003 Server. Locally, I have installed Oracle Data Access Components v11.1.0.6.20.
Thanks!
Are you watching your output window for any exceptions? I don't see any catch blocks in your code.
Oracle's ODP.net has almost exactly the same syntax as ADO, but performs better in many situations. If you're only using Oracle, it might be worth a look.
Is there a reason to use StringBuilder? A single string variable will perform better and makes code easier to read.
It seems that the queries were actually returning, just taking a very long time due to poor query performance, low bandwidth, and the enormous amount of rows being returned. The VS debugger seems to give up after a few seconds for these long-running queries. However, if I let it sit for a few minutes my breakpoints would get hit and things would work as expected.
Thanks for the replies / comments!

Resources