/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.
This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Data.Common;
using System.Configuration;
using System.Text.RegularExpressions;
using Everest.Library.ExtensionMethod;
using Everest.CmsServices.Services;
using Everest.CmsServices.Installation;
using Everest.CmsServices.Extension.Module;
namespace Everest.CmsServices.Installation{
public abstract class UpdaterBase
{
const string Site_TempateFolder = "Site_Template";
public virtual void Upgrade(KoobooInstance olderInstance, KoobooInstance newerInstance, bool upgradeDb, bool copyContentFiles)
{
if (olderInstance.Version >= newerInstance.Version)
{
throw new Exception(string.Format(Resources.Upgrade_VersionConflict, olderInstance.Version, newerInstance.Version));
}
CopyBin(olderInstance.KoobooPath, newerInstance.KoobooPath);
CopyTemplates(olderInstance.KoobooPath, newerInstance.KoobooPath);
CopyAppData(olderInstance.KoobooPath, newerInstance.KoobooPath);
CopyAssemblies(olderInstance.KoobooPath, newerInstance.KoobooPath);
CopyModules(olderInstance.KoobooPath, newerInstance.KoobooPath);
if (copyContentFiles)
{
CopyContentFiles(olderInstance.KoobooPath, newerInstance.KoobooPath);
}
UpgradeConfig(olderInstance, newerInstance);
if (upgradeDb)
{
UpgradeDatabase(olderInstance, newerInstance);
}
}
protected virtual void CopyBin(string olderKoobooPath, string newerKoobooPath)
{
var srcDir = Path.Combine(olderKoobooPath, "Bin");
var targetDir = Path.Combine(newerKoobooPath, "Bin");
FileExtensions.CopyDirectory(srcDir, targetDir, false);
}
protected virtual void CopyTemplates(string olderKoobooPath, string newerKoobooPath)
{
var srcTemplateDir = new DirectoryInfo(Path.Combine(olderKoobooPath, "Template"));
if (srcTemplateDir.Exists)
{
string targetTemplatePath = Path.Combine(newerKoobooPath, "Template");
foreach (var dir in srcTemplateDir.GetDirectories())
{
if (!dir.Name.Equals(Site_TempateFolder, StringComparison.InvariantCultureIgnoreCase))
{
string targetDir = Path.Combine(targetTemplatePath, dir.Name);
FileExtensions.CopyDirectory(dir.FullName, targetDir);
}
}
}
}
protected virtual void CopyContentFiles(string olderKoobooPath, string newerKoobooPath)
{
string srcDir = Path.Combine(olderKoobooPath, "ContentFiles");
string targetDir = Path.Combine(newerKoobooPath, "ContentFiles");
if (Directory.Exists(srcDir))
{
FileExtensions.CopyDirectory(srcDir, targetDir);
}
}
protected virtual void CopyAppData(string olderKoobooPath, string newerKoobooPath)
{
string srcDir = Path.Combine(olderKoobooPath, "App_Data");
string targetDir = Path.Combine(newerKoobooPath, "App_Data");
if (Directory.Exists(srcDir))
{
FileExtensions.CopyDirectory(srcDir, targetDir);
}
}
protected virtual void CopyAssemblies(string olderKoobooPath, string newerKoobooPath)
{
string srcDir = Path.Combine(olderKoobooPath, AssemblyFileManager.AssemblyDirName);
string targetDir = Path.Combine(newerKoobooPath, AssemblyFileManager.AssemblyDirName);
if (Directory.Exists(srcDir))
{
FileExtensions.CopyDirectory(srcDir, targetDir);
}
}
protected virtual void CopyModules(string olderKoobooPath, string newerKoobooPath)
{
string srcDir = Path.Combine(olderKoobooPath, ModuleManager.ModuleDirName);
string targetDir = Path.Combine(newerKoobooPath, ModuleManager.ModuleDirName);
if (Directory.Exists(srcDir))
{
FileExtensions.CopyDirectory(srcDir, targetDir);
}
}
public abstract void UpgradeConfig(KoobooInstance olderInstance, KoobooInstance newerInstance);
public virtual void UpgradeDatabase(KoobooInstance olderInstance, KoobooInstance newerInstance)
{
string getVersionSQL = "SELECT CompatibleSchemaVersion FROM aspnet_SchemaVersions WHERE Feature='kooboo'";
var versionValue = DbHelper.ExecuteScalar(DbFactory, ParseConnectionString(olderInstance.ConnectionString, newerInstance.KoobooPath), getVersionSQL);
if (versionValue == null)
{
versionValue = olderInstance.Version;
}
var dbVersion = new Version(versionValue.ToString());
if (dbVersion != olderInstance.Version)
{
throw new Exception(Resources.Upgrade_DbVersionConflict);
}
ExecuteUpgradeSQL(olderInstance, newerInstance);
}
static Regex goRegex = new Regex("^GO\r", RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
private void ExecuteUpgradeSQL(KoobooInstance olderInstance, KoobooInstance newerInstance)
{
var dbFactory = DbFactory;
var connectionString = ParseConnectionString(olderInstance.ConnectionString, newerInstance.KoobooPath);
var upgrades = GetAllUpgradeSQL(newerInstance.KoobooPath, olderInstance.Version, newerInstance.Version);
var backupFile = BackupDatabase(connectionString);
try
{
foreach (var dir in upgrades.Values)
{
var files = dir.GetFiles().OrderBy(f => f.Name);
foreach (var file in files)
{
string sql = goRegex.Replace(FileExtensions.GetFileBody(file.FullName), "");
DbHelper.ExecuteNoQuery(dbFactory, connectionString, sql);
}
}
}
catch (Exception e)
{
throw new Exception(string.Format(Resources.Upgrade_UpgradeDbError, backupFile, e.Message));
}
}
protected abstract string BackupDatabase(string connectionString);
private SortedDictionary<Version, DirectoryInfo> GetAllUpgradeSQL(string newerKoobooPath, Version olderVersion, Version newerVersion)
{
SortedDictionary<Version, DirectoryInfo> upgrades = new SortedDictionary<Version, DirectoryInfo>();
var sqlDirInfo = new DirectoryInfo(Path.Combine(newerKoobooPath, SQLFolder));
foreach (var dir in sqlDirInfo.GetDirectories())
{
var versions = dir.Name.Split('-');
var fromVersion = new Version(versions[0].Trim());
var toVersion = new Version(versions[1].Trim());
if (fromVersion >= olderVersion && fromVersion < newerVersion && toVersion <= newerVersion)
{
upgrades.Add(fromVersion, dir);
}
}
return upgrades;
}
protected abstract string SQLFolder { get; }
protected abstract DbProviderFactory DbFactory { get; }
protected virtual string ParseConnectionString(string connectionString, string koobooPath)
{
DbConnectionStringBuilder connectionStringBuilder = DbFactory.CreateConnectionStringBuilder();
connectionStringBuilder.ConnectionString = connectionString;
var dataSource = connectionStringBuilder["data source"].ToString();
if (dataSource.ToLower().Contains("|datadirectory|"))
{
string dbName = dataSource.Replace("|datadirectory|", "", true);
connectionStringBuilder["data source"] = string.Format("{0}\\App_Data\\{1}", koobooPath, dbName);
return connectionStringBuilder.ConnectionString;
}
return connectionString;
}
}
}
|