Sunday, August 10, 2008

sqlite database encryption

copied from http://sqlite.phxsoftware.com/forums/t/130.aspx

Encrypt sqlite by using System.Data.SQLite.dll is pretty simple.

To encrypt an existing unencrypted database, or to change the password of an encrypted database, open the database and then use the ChangePassword() function of SQLiteConnection:


// Opens an unencrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
// Encrypts the database. The connection remains valid and usable afterwards.
cnn.ChangePassword("mypassword");


To decrypt an existing encrypted database call ChangePassword() with a NULL or "" password:


// Opens an encrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3;Password=mypassword");
cnn.Open();
// Removes the encryption on an encrypted database.
cnn.ChangePassword(null);

To open an existing encrypted database, or to create a new encrypted database, specify a password in the ConnectionString as shown in the previous example, or call the SetPassword() function before opening a new SQLiteConnection. Passwords specified in the ConnectionString must be cleartext, but passwords supplied in the SetPassword() function may be binary byte arrays.


// Opens an encrypted database by calling SetPassword()
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.SetPassword(new byte[] { 0xFF, 0xEE, 0xDD, 0x10, 0x20, 0x30 });
cnn.Open();
// The connection is now usable

By default, the ATTACH keyword will use the same encryption key as the main database when attaching another database file to an existing connection. To change this behavior, you use the KEY modifier as follows:
If you are attaching an encrypted database using a cleartext password:


// Attach to a database using a different key than the main database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY 'mypassword'", cnn);
cmd.ExecuteNonQuery();

To attach an encrypted database using a binary password:


// Attach to a database encrypted with a binary key
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY X'FFEEDD102030'", cnn);
cmd.ExecuteNonQuery();

Monday, July 28, 2008

NDbUnit Framework

NDbUnit test is a good UnitTest framework if you are familiar with C#. But this project seems not active since 2006.
Home Page: http://qualitylabs.org/projects/ndbunit/

Monday, July 21, 2008

SQL 2005 Restore database error

当我用SQL Server 2005 restore一个数据库时候, 总是报下面的错. 我试着用sa登录,试着用Windows Authentication方式登录都不行.
System.Data.SqlClient.SqlError: The operating system returned the error '5(Access is denied.)' while attempting 'RestoreContainer::ValidateTargetForCreation' on 'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DWH.mdf'. (Microsoft.SqlServer.Express.Smo)

google之后, 发现原因是SQL Server服务的账号必须有权限读写mdf文件. 而SQL Server 2005服务可以用指定的windows账号来启动, 仅仅内建的启动账号就有local system,local service和network service三种, 还可以用其他账号来启动.
出现restore错误时候, SQL Server2005是由network service账号来启动的, 该账号没有权限读写mdf文件. 所以需要切换启动账号, 可以用SQL Server configuration manager这个工具.

The service account for sqlexpress does not have access/permission. Use Configuration Mgr to change the startup account to LocalSystem (if your database and backup file are on the local machine) or a domain user account that has permission to disk resources (locally and remotely).

Wednesday, June 4, 2008

Exploring Table and Index Partitioning in SQL Server 2005

参考 http://www.sqljunkies.com/article/f4920050-6c63-4109-93ff-c2b7eb0a5835.scuk

Indexed Views in SQL Server 2000

参考 http://www.sqlteam.com/article/indexed-views-in-sql-server-2000

When and where do we use hash index in sql server

参考http://www.fotia.co.uk/fotia/Blog/2006/01/hash-indexes.html
当我设计一个Product表的时候, 对于ProductName这个字段的数据类型, 我一直拿捏不定, 最后为了不至于ProductName被截断, 我选用了NVarchar(4000), 我没有选择Text(NText)类型, 因为在SQL Server 2005中,它们被标记为Deprecated.
幸运的是,我选取了NVarchar(4000), 在实际情况下, 有个名称也确实够长, 足足1000个byte.
同时我又需要在ProductName上创建Index, 对于length>=900byte的字段, 将SQL Server拒绝为你创建普通的index.
怎么办呢? 我们可以为ProductName这样的长字段, 创建Hash Index, 方法是:
第一步, 为Product表创建一个计算列, 比如ProductNameHashField, 让它的值为CheckSum(ProductName), 这个字段的值将是Integer类型.
第二步, 创建一个ProductNameHashField字段的Index, 名为IX_Product_NameHash


-- Index it. Note that this is a non-unqiue index for collisions.
create index IX_Product_NameHash
on Product(ProductNameHashField);
go

怎么利用这个Hash Index, 来加速我们的query呢?


-- Look for the hash of the DName.
-- Always, always include the original data in case of collisions.
select customerId
from Product
where ProductNameHashField= checksum(@ProductName)-- this is the key to speed up query
and ProductName= @ProductName
go

通过观察执行计划, 发现查询速度确实有了很大的提高.

sqlite provider for ado.net

ado.net 2 dll download
http://sqlite.phxsoftware.com/

http://sourceforge.net/projects/sqlite-dotnet2