Upgrading WinForms SQLite Database techniques

梦想的初衷 提交于 2019-12-06 07:25:43

A simple approach is to have a special table in your db. Let's assume that this special table is called DBVersion. This table contains only a row with one single numeric column that contain the version number of your database. Initially this table contains the value 0

Now suppose that you have an XML file with a similar schema

<?xml version="1.0" standalone="yes"?>
<DatabaseUpdater>
  <xs:schema id="DatabaseUpdater" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="DatabaseUpdater" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="UpdateCMD">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="DBType" type="xs:int" minOccurs="0" />
                <xs:element name="Version" type="xs:int" minOccurs="0" />
                <xs:element name="Command" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <UpdateCMD>
    <DBType>1</DBType>
    <Version>1</Version>
    <Command>CREATE TABLE userTable ......
    </Command>
  </UpdateCMD>
</DatabaseUpdater>

Now you could write code that read the database DBVersion table number and then load the XML file, search for commands with a Version value higher than the version number in the DBVersion table and execute them. After successful execution, update the Version number in the DBVersion table. (Special care should be taken here to avoid errors and a log file should be imperative).

int currentVersion = GetDBVersionNumber();

string scriptFile = "UPGRADE_DB.XML";
DataSet ds = new DataSet();
ds.ReadXml(scriptFile, XmlReadMode.ReadSchema);

string filter = "Version > " + currentVersion.ToString();
string sort = "Version";

DataRow[] rows = ds.Tables[0].Select(filter, sort);
if (rows.Length == 0)
    return;

try
{
    using(SQLiteConnection cnn = new SQLiteConnection(.....))
    using(SQLiteCommand cmd = cnn.GetCommand())
    {
        foreach (DataRow dr in rows)
        {
            cmd.CommandText = dr.Field<string>("Command");
            cmd.CommandType = CommandType.Text;
            cmd.ExecuteNonQuery();
            UpdateDBVersionNumber(dr.Field<int>("Version"));
            WriteLog(currentVersion);
        }
    }
}
catch(Exception ex)
{
    WriteLog(ex);
}

When you need to upgrade your database you simply add another 'record' to the XML file and distribute it to your customers. The application should be able to upgrade the database without any change in your code for this specific purpose

The most widely used way is that used by Android: this is handled with the SQLiteOpenHelper class, which stores a version number in the database (using PRAGMA user_version, but the exact mechanism does not matter) and has onCreate/onUpdate callbacks for the app to handle these cases.

You don't need to check individual tables; the database version number takes care of that. (You can keep everything consistent by putting the entire update into a transaction.)

Look at the source (especially getDatabaseLocked) and implement something similar.


When you have multiple older versions, a typical way to handle this is as follows:

if (oldVersion < 2)
{
    // update everything from version 1 to 2
}
if (oldVersion < 3)
{
    // update everything from version 2 to 3
}
...
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!