mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-08 00:14:31 +08:00
Compare commits
1 Commits
issue/8232
...
feature/sq
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8be940fe8d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -166,6 +166,8 @@ build/
|
||||
/artifacts
|
||||
*.sln.cache
|
||||
src/Orchard.Web/Media/*
|
||||
src/Orchard.Web/x86
|
||||
src/Orchard.Web/amd64
|
||||
log.xml
|
||||
profiling/
|
||||
*.orig
|
||||
|
12
CREDITS.txt
12
CREDITS.txt
@@ -265,6 +265,18 @@ Website: https://github.com/sayedihashimi/package-web/
|
||||
Copyright: Copyright 2013 Sayed Ibrahim Hashimi
|
||||
License: Apache 2.0
|
||||
|
||||
SQLite
|
||||
-----
|
||||
Website: http://sqlite.org
|
||||
Copyright: Public Domain
|
||||
License: Public Domain
|
||||
|
||||
SQLite CREATE Statement Parser for .Net
|
||||
-----
|
||||
Website: https://github.com/ericschultz/SQLiteParser
|
||||
Copyright: Copyright 2014 Outercurve Foundation
|
||||
License: MIT
|
||||
|
||||
SpecFlow
|
||||
-----
|
||||
Website: http://www.specflow.org/
|
||||
|
@@ -10,6 +10,7 @@
|
||||
<MsBuildTasksFolder>$(MSBuildProjectDirectory)\buildtasks</MsBuildTasksFolder>
|
||||
<ArtifactsFolder>$(MSBuildProjectDirectory)\artifacts</ArtifactsFolder>
|
||||
<SqlCeFolder>$(MSBuildProjectDirectory)\lib\sqlce</SqlCeFolder>
|
||||
<SQLiteFolder>$(MSBuildProjectDirectory)\lib\sqlite</SQLiteFolder>
|
||||
<SourceArtifactFolder>$(ArtifactsFolder)\Source</SourceArtifactFolder>
|
||||
<MsDeployArtifactFolder>$(ArtifactsFolder)\MsDeploy</MsDeployArtifactFolder>
|
||||
<GalleryArtifactFolder>$(ArtifactsFolder)\Gallery</GalleryArtifactFolder>
|
||||
@@ -189,6 +190,8 @@
|
||||
<ItemGroup>
|
||||
<SqlCe-Native-Binaries-x86 Include="$(SqlCeFolder)\x86\**\*"/>
|
||||
<SqlCe-Native-Binaries-amd64 Include="$(SqlCeFolder)\amd64\**\*"/>
|
||||
<SQLite-Native-Binaries-x86 Include="$(SQLiteFolder)\x86\**\*"/>
|
||||
<SQLite-Native-Binaries-amd64 Include="$(SQLiteFolder)\amd64\**\*"/>
|
||||
<Stage-Orchard-Web-Bins Include="$(WebSitesFolder)\Orchard.Web\bin\*"/>
|
||||
<Stage-Bin-Exclude Include="$(WebSitesFolder)\**\bin\**\*" />
|
||||
<Stage-Web Include="$(WebSitesFolder)\Orchard.Web\**\*;$(SrcFolder)\Orchard.Web\*.csproj;" Exclude="$(SrcFolder)\Orchard.Web\Orchard.Web.csproj;$(SrcFolder)\Orchard.Web\**\*.Release.config;$(SrcFolder)\Orchard.Web\**\*.Debug.config"/>
|
||||
@@ -259,6 +262,8 @@
|
||||
<Copy SourceFiles="@(Stage-PoFiles)" DestinationFolder="$(StageFolder)\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(SqlCe-Native-Binaries-x86)" DestinationFolder="$(StageFolder)\bin\x86\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(SqlCe-Native-Binaries-amd64)" DestinationFolder="$(StageFolder)\bin\amd64\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(SQLite-Native-Binaries-x86)" DestinationFolder="$(StageFolder)\bin\x86\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(SQLite-Native-Binaries-amd64)" DestinationFolder="$(StageFolder)\bin\amd64\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(Stage-Core)" DestinationFolder="$(StageFolder)\Core\%(RecursiveDir)"/>
|
||||
<Copy SourceFiles="@(Stage-Modules)" DestinationFiles="@(Stage-Modules->'$(StageFolder)\Modules\%(ModuleName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
|
||||
<Copy SourceFiles="@(Stage-Modules-Binaries-Unique)" DestinationFiles="@(Stage-Modules-Binaries-Unique->'$(StageFolder)\Modules\%(ModuleName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
|
||||
|
BIN
lib/antlr/Antlr4.Runtime.v4.0.dll
Normal file
BIN
lib/antlr/Antlr4.Runtime.v4.0.dll
Normal file
Binary file not shown.
6536
lib/antlr/Antlr4.Runtime.v4.0.xml
Normal file
6536
lib/antlr/Antlr4.Runtime.v4.0.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
lib/sqlite-createsupport/Outercurve.SQLiteCreateTree.dll
Normal file
BIN
lib/sqlite-createsupport/Outercurve.SQLiteCreateTree.dll
Normal file
Binary file not shown.
BIN
lib/sqlite-createsupport/Outercurve.SQLiteCreateTree.pdb
Normal file
BIN
lib/sqlite-createsupport/Outercurve.SQLiteCreateTree.pdb
Normal file
Binary file not shown.
30
lib/sqlite-createsupport/Outercurve.SQLiteCreateTree.xml
Normal file
30
lib/sqlite-createsupport/Outercurve.SQLiteCreateTree.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Outercurve.SQLiteCreateTree</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:Outercurve.SQLiteCreateTree.AlterTable.NativeAlterTableProcessor.CreateSqlStatements(Outercurve.SQLiteCreateTree.AlterTable.Action.AlterTableCommand)">
|
||||
<summary>
|
||||
returns null if something if we don't have ones we can do natively
|
||||
</summary>
|
||||
<param name="command"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:Outercurve.SQLiteCreateTree.Nodes.ColumnConstraint.UniqueConstraintNode.ConflictClause">
|
||||
<summary>
|
||||
Conflict Clause is really weird, it can be empty. We treat that as null.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Outercurve.SQLiteCreateTree.Nodes.ForeignDeferrableNode.IsDeferrable">
|
||||
<summary>
|
||||
NOT?
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Outercurve.SQLiteCreateTree.Nodes.ForeignDeferrableNode.InitiallyImmediate">
|
||||
<summary>
|
||||
((INITIALLY DEFERRED)| (INITIALLY IMMEDIATE))?
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
BIN
lib/sqlite-createsupport/Outercurve.SQLiteParser.dll
Normal file
BIN
lib/sqlite-createsupport/Outercurve.SQLiteParser.dll
Normal file
Binary file not shown.
BIN
lib/sqlite-createsupport/Outercurve.SQLiteParser.pdb
Normal file
BIN
lib/sqlite-createsupport/Outercurve.SQLiteParser.pdb
Normal file
Binary file not shown.
1103
lib/sqlite-createsupport/Outercurve.SQLiteParser.xml
Normal file
1103
lib/sqlite-createsupport/Outercurve.SQLiteParser.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
lib/sqlite/System.Data.SQLite.dll
Normal file
BIN
lib/sqlite/System.Data.SQLite.dll
Normal file
Binary file not shown.
121
lib/sqlite/System.Data.SQLite.dll.config
Normal file
121
lib/sqlite/System.Data.SQLite.dll.config
Normal file
@@ -0,0 +1,121 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
*
|
||||
* System.Data.SQLite.dll.config -
|
||||
*
|
||||
* Written by Joe Mistachkin.
|
||||
* Released to the public domain, use at your own risk!
|
||||
*
|
||||
-->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], the SQLite
|
||||
logging subsystem may be initialized in a non-default application
|
||||
domain. By default, this is not allowed due to the potential
|
||||
for application domain unloading issues.
|
||||
-->
|
||||
<!--
|
||||
<add key="Force_SQLiteLog" value="1" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], the native
|
||||
library pre-loading functionality will be disabled. By default,
|
||||
the native library pre-loading will attempt to load the native
|
||||
SQLite library from architecture-specific (e.g. "x86", "amd64",
|
||||
"x64") or platform-specific (e.g. "Win32") directories that
|
||||
reside underneath the application base directory.
|
||||
-->
|
||||
<!--
|
||||
<add key="No_PreLoadSQLite" value="1" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], the new
|
||||
connection string parsing algorithm will not be used. This
|
||||
environment variable is intended for use with legacy code only.
|
||||
-->
|
||||
<!--
|
||||
<add key="No_SQLiteConnectionNewParser" value="1" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], the initial
|
||||
search for types in all loaded assemblies that are tagged with
|
||||
the SQLiteFunction attribute will be skipped. Normally, this
|
||||
search is conducted only once per application domain by the
|
||||
static constructor of the SQLiteFunction class; however, these
|
||||
implementation details are subject to change.
|
||||
-->
|
||||
<!--
|
||||
<add key="No_SQLiteFunctions" value="1" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], it will be
|
||||
used instead of the application base directory by the native
|
||||
library pre-loader. This environment variable can be especially
|
||||
useful in ASP.NET and other hosted environments where direct
|
||||
control of the location of the managed assemblies is not under
|
||||
the control of the application.
|
||||
-->
|
||||
<!--
|
||||
<add key="PreLoadSQLite_BaseDirectory" value="" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], it will be
|
||||
used instead of the processor architecture value contained in the
|
||||
PROCESSOR_ARCHITECTURE environment variable to help build the
|
||||
path of the native library to pre-load.
|
||||
-->
|
||||
<!--
|
||||
<add key="PreLoadSQLite_ProcessorArchitecture" value="x86" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this environment variable is set [to anything], the native
|
||||
library pre-loading code will skip conducting a search for the
|
||||
native library to pre-load. By default, the search starts in the
|
||||
location of the currently executing assembly (i.e. the assembly
|
||||
containing all the managed components for System.Data.SQLite) and
|
||||
then falls back to the application domain base directory.
|
||||
-->
|
||||
<!--
|
||||
<add key="PreLoadSQLite_NoSearchForDirectory" value="1" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this configuration variable is set [to anything], the location
|
||||
of the currently executing assembly (i.e. the one containing all
|
||||
the managed components for System.Data.SQLite) will be used as
|
||||
the basis for locating the the native library to pre-load (i.e.
|
||||
instead of using the application domain base directory).
|
||||
-->
|
||||
<!--
|
||||
<add key="PreLoadSQLite_UseAssemblyDirectory" value="1" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: This configuration variable is normally set by the operating
|
||||
system itself and should reflect the native processor
|
||||
architecture of the current process (e.g. a 32-bit x86
|
||||
application running on a 64-bit x64 operating system should have
|
||||
the value "x86").
|
||||
-->
|
||||
<!--
|
||||
<add key="PROCESSOR_ARCHITECTURE" value="%PROCESSOR_ARCHITECTURE%" />
|
||||
-->
|
||||
|
||||
<!--
|
||||
NOTE: If this environment variable is set [to anything], it will be
|
||||
used by the System.Data.SQLite.SQLiteFactory class as the type
|
||||
name containing the System.Data.Common.DbProviderServices
|
||||
implementation that should be used.
|
||||
-->
|
||||
<!--
|
||||
<add key="TypeName_SQLiteProviderServices" value="" />
|
||||
-->
|
||||
</appSettings>
|
||||
</configuration>
|
BIN
lib/sqlite/System.Data.SQLite.pdb
Normal file
BIN
lib/sqlite/System.Data.SQLite.pdb
Normal file
Binary file not shown.
13100
lib/sqlite/System.Data.SQLite.xml
Normal file
13100
lib/sqlite/System.Data.SQLite.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
lib/sqlite/x64/SQLite.Interop.dll
Normal file
BIN
lib/sqlite/x64/SQLite.Interop.dll
Normal file
Binary file not shown.
BIN
lib/sqlite/x64/SQLite.Interop.pdb
Normal file
BIN
lib/sqlite/x64/SQLite.Interop.pdb
Normal file
Binary file not shown.
BIN
lib/sqlite/x86/SQLite.Interop.dll
Normal file
BIN
lib/sqlite/x86/SQLite.Interop.dll
Normal file
Binary file not shown.
82
src/Orchard.Tests/DataMigration/SQLite/SQLiteDataUtility.cs
Normal file
82
src/Orchard.Tests/DataMigration/SQLite/SQLiteDataUtility.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentNHibernate;
|
||||
using FluentNHibernate.Automapping;
|
||||
using FluentNHibernate.Automapping.Alterations;
|
||||
using FluentNHibernate.Cfg;
|
||||
using FluentNHibernate.Diagnostics;
|
||||
using NHibernate;
|
||||
using NHibernate.Tool.hbm2ddl;
|
||||
using Orchard.Data;
|
||||
using Orchard.Data.Providers;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
|
||||
namespace Orchard.Tests.DataMigration.SQLite {
|
||||
public static class SQLiteDataUtility {
|
||||
public static ISessionFactory CreateSessionFactory(string fileName, params Type[] types) {
|
||||
|
||||
//var persistenceModel = AutoMap.Source(new Types(types))
|
||||
// .Alterations(alt => AddAlterations(alt, types))
|
||||
// .Conventions.AddFromAssemblyOf<DataModule>();
|
||||
var persistenceModel = AbstractDataServicesProvider.CreatePersistenceModel(types.Select(t => new RecordBlueprint { TableName = "Test_" + t.Name, Type = t }).ToList());
|
||||
var persistenceConfigurer = new SQLiteDataServicesProvider(fileName).GetPersistenceConfigurer(true/*createDatabase*/);
|
||||
|
||||
|
||||
return Fluently.Configure()
|
||||
.Database(persistenceConfigurer)
|
||||
.Mappings(m => m.AutoMappings.Add(persistenceModel))
|
||||
.ExposeConfiguration(c => {
|
||||
// This is to work around what looks to be an issue in the NHibernate driver:
|
||||
// When inserting a row with IDENTITY column, the "SELET @@IDENTITY" statement
|
||||
// is issued as a separate command. By default, it is also issued in a separate
|
||||
// connection, which is not supported (returns NULL).
|
||||
c.SetProperty("connection.release_mode", "on_close");
|
||||
new SchemaExport(c).Create(false /*script*/, true /*export*/);
|
||||
})
|
||||
.BuildSessionFactory();
|
||||
}
|
||||
|
||||
private static void AddAlterations(AutoMappingAlterationCollection alterations, IEnumerable<Type> types) {
|
||||
foreach (var assembly in types.Select(t => t.Assembly).Distinct()) {
|
||||
alterations.Add(new AutoMappingOverrideAlteration(assembly));
|
||||
alterations.AddFromAssembly(assembly);
|
||||
}
|
||||
alterations.AddFromAssemblyOf<DataModule>();
|
||||
}
|
||||
|
||||
public static ISessionFactory CreateSessionFactory(params Type[] types) {
|
||||
return CreateSessionFactory(
|
||||
types.Aggregate("db", (n, t) => t.FullName + "." + n),
|
||||
types);
|
||||
}
|
||||
|
||||
#region Nested type: Types
|
||||
|
||||
private class Types : ITypeSource {
|
||||
private readonly IEnumerable<Type> _types;
|
||||
|
||||
public Types(params Type[] types) {
|
||||
_types = types;
|
||||
}
|
||||
|
||||
#region ITypeSource Members
|
||||
|
||||
public IEnumerable<Type> GetTypes() {
|
||||
return _types;
|
||||
}
|
||||
|
||||
public void LogSource(IDiagnosticLogger logger) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetIdentifier() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,210 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using NHibernate;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Data;
|
||||
using Orchard.Data.Migration.Interpreters;
|
||||
using Orchard.Data.Migration.Schema;
|
||||
using Orchard.Data.Providers;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.ShellBuilders.Models;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Reports.Services;
|
||||
using Orchard.Tests.ContentManagement;
|
||||
using System.IO;
|
||||
using Orchard.Tests.Environment;
|
||||
using Orchard.Tests.FileSystems.AppData;
|
||||
using Orchard.Tests.Stubs;
|
||||
|
||||
namespace Orchard.Tests.DataMigration.SQLite {
|
||||
[TestFixture]
|
||||
public class SQLiteSchemaBuilderTestsBase {
|
||||
private IContainer _container;
|
||||
private ISessionFactory _sessionFactory;
|
||||
private string _databaseFileName;
|
||||
private string _tempFolder;
|
||||
private SchemaBuilder _schemaBuilder;
|
||||
private DefaultDataMigrationInterpreter _interpreter;
|
||||
private ISession _session;
|
||||
|
||||
[SetUp]
|
||||
public void Setup() {
|
||||
_databaseFileName = Path.GetTempFileName();
|
||||
_sessionFactory = SQLiteDataUtility.CreateSessionFactory(_databaseFileName);
|
||||
|
||||
_tempFolder = Path.GetTempFileName();
|
||||
File.Delete(_tempFolder);
|
||||
var appDataFolder = AppDataFolderTests.CreateAppDataFolder(_tempFolder);
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
|
||||
_session = _sessionFactory.OpenSession();
|
||||
builder.RegisterInstance(appDataFolder).As<IAppDataFolder>();
|
||||
builder.RegisterType<SQLiteDataServicesProvider>().As<IDataServicesProvider>();
|
||||
builder.RegisterType<DataServicesProviderFactory>().As<IDataServicesProviderFactory>();
|
||||
builder.RegisterType<DefaultDataMigrationInterpreter>().As<IDataMigrationInterpreter>();
|
||||
builder.RegisterType<SQLiteCommandInterpreter>().As<ICommandInterpreter>();
|
||||
builder.RegisterType<SessionConfigurationCache>().As<ISessionConfigurationCache>();
|
||||
builder.RegisterType<SessionFactoryHolder>().As<ISessionFactoryHolder>();
|
||||
builder.RegisterType<DefaultDatabaseCacheConfiguration>().As<IDatabaseCacheConfiguration>();
|
||||
builder.RegisterType<StubHostEnvironment>().As<IHostEnvironment>();
|
||||
builder.RegisterInstance(new ShellBlueprint { Records = Enumerable.Empty<RecordBlueprint>() }).As<ShellBlueprint>();
|
||||
builder.RegisterInstance(new ShellSettings { Name = "temp", DataProvider = "SQLite", DataTablePrefix = "TEST" }).As<ShellSettings>();
|
||||
builder.RegisterType<DialectService>().As<IDialectService>();
|
||||
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
|
||||
builder.RegisterModule(new DataModule());
|
||||
_container = builder.Build();
|
||||
|
||||
_interpreter = _container.Resolve<IDataMigrationInterpreter>() as DefaultDataMigrationInterpreter;
|
||||
_schemaBuilder = new SchemaBuilder(_interpreter);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllMethodsShouldBeCalledSuccessfully() {
|
||||
|
||||
_schemaBuilder
|
||||
.CreateTable("User", table => table
|
||||
.ContentPartRecord()
|
||||
.Column("Firstname", DbType.String, column => column.WithLength(255))
|
||||
.Column("Lastname", DbType.String, column => column.WithPrecision(0).WithScale(1)))
|
||||
.CreateTable("Address", table => table
|
||||
.ContentPartVersionRecord()
|
||||
.Column("City", DbType.String)
|
||||
.Column("ZIP", DbType.Int32, column => column.Unique())
|
||||
.Column("UserId", DbType.Int32, column => column.NotNull()))
|
||||
.CreateForeignKey("User_Address", "Address", new[] { "UserId" }, "User", new[] { "Id" })
|
||||
.AlterTable("User", table => table
|
||||
.AddColumn("Age", DbType.Int32))
|
||||
.AlterTable("User", table => table
|
||||
.DropColumn("Lastname"))
|
||||
.AlterTable("User", table => table
|
||||
.CreateIndex("IDX_XYZ", "Firstname"))
|
||||
.AlterTable("User", table => table
|
||||
.DropIndex("IDX_XYZ"))
|
||||
.DropForeignKey("Address", "User_Address")
|
||||
.DropTable("Address");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateCommandShouldBeHandled() {
|
||||
|
||||
_schemaBuilder
|
||||
.CreateTable("User", table => table
|
||||
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
|
||||
.Column("Firstname", DbType.String, column => column.WithLength(255))
|
||||
.Column("Lastname", DbType.String, column => column.WithLength(100).NotNull())
|
||||
.Column("SN", DbType.AnsiString, column => column.WithLength(40).Unique())
|
||||
.Column("Salary", DbType.Decimal, column => column.WithPrecision(9).WithScale(2))
|
||||
.Column("Gender", DbType.Decimal, column => column.WithDefault(""))
|
||||
);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DropTableCommandShouldBeHandled() {
|
||||
_schemaBuilder
|
||||
.CreateTable("User", table => table
|
||||
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
|
||||
.Column("Firstname", DbType.String, column => column.WithLength(255))
|
||||
.Column("Lastname", DbType.String, column => column.WithLength(100).NotNull())
|
||||
.Column("SN", DbType.AnsiString, column => column.WithLength(40).Unique())
|
||||
.Column("Salary", DbType.Decimal, column => column.WithPrecision(9).WithScale(2))
|
||||
.Column("Gender", DbType.Decimal, column => column.WithDefault(""))
|
||||
);
|
||||
|
||||
_schemaBuilder
|
||||
.DropTable("User");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CustomSqlStatementsShouldBeHandled() {
|
||||
|
||||
_schemaBuilder
|
||||
.ExecuteSql("select 1");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AlterTableCommandShouldBeHandled() {
|
||||
|
||||
_schemaBuilder
|
||||
.CreateTable("User", table => table
|
||||
.Column("Firstname", DbType.String, column => column.WithLength(255))
|
||||
.Column("Lastname", DbType.String, column => column.WithLength(100).NotNull()))
|
||||
.AlterTable("User", table => table
|
||||
.AddColumn("Age", DbType.Int32))
|
||||
.AlterTable("User", table => table
|
||||
.AlterColumn("Lastname", column => column.WithDefault("Doe")))
|
||||
.AlterTable("User", table => table
|
||||
.DropColumn("Firstname")
|
||||
);
|
||||
|
||||
// creating a new row should assign a default value to Firstname and Age
|
||||
_schemaBuilder.ExecuteSql("insert into TEST_User DEFAULT VALUES;");
|
||||
|
||||
// ensure we have one record with the default value
|
||||
var query = _session.CreateSQLQuery("SELECT count() FROM TEST_User WHERE Lastname = 'Doe'");
|
||||
Assert.That(query.UniqueResult<long>(), Is.EqualTo(1));
|
||||
|
||||
// ensure this is not a false positive
|
||||
query = _session.CreateSQLQuery("SELECT count(*) FROM TEST_User WHERE Lastname = 'Foo'");
|
||||
Assert.That(query.UniqueResult<long>(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ForeignKeyShouldBeCreatedAndRemoved() {
|
||||
|
||||
_schemaBuilder
|
||||
.CreateTable("User", table => table
|
||||
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
|
||||
.Column("Firstname", DbType.String, column => column.WithLength(255))
|
||||
.Column("Lastname", DbType.String, column => column.WithPrecision(0).WithScale(1)))
|
||||
.CreateTable("Address", table => table
|
||||
.Column("City", DbType.String)
|
||||
.Column("ZIP", DbType.Int32, column => column.Unique())
|
||||
.Column("UserId", DbType.Int32, column => column.NotNull()))
|
||||
.CreateForeignKey("FK_User", "Address", new[] { "UserId" }, "User", new[] { "Id" })
|
||||
.DropForeignKey("Address", "FK_User");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void ShouldAllowFieldSizeAlteration() {
|
||||
_schemaBuilder
|
||||
.CreateTable("ContentItemRecord", table => table
|
||||
.Column("Id", DbType.Int32, column => column.PrimaryKey().Identity())
|
||||
.Column("Data", DbType.String, column => column.WithLength(255)));
|
||||
|
||||
// should write successfully less than 255 chars
|
||||
_schemaBuilder
|
||||
.ExecuteSql("insert into TEST_ContentItemRecord (Data) values('Hello World')");
|
||||
|
||||
_schemaBuilder
|
||||
.AlterTable("ContentItemRecord", table => table
|
||||
.AlterColumn("Data", column => column.WithType(DbType.String).WithLength(2048)));
|
||||
|
||||
// should write successfully a bigger value now
|
||||
_schemaBuilder
|
||||
.ExecuteSql(String.Format("insert into TEST_ContentItemRecord (Data) values('{0}')", new String('x', 2048)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void PrecisionAndScaleAreApplied() {
|
||||
|
||||
_schemaBuilder
|
||||
.CreateTable("Product", table => table
|
||||
.Column("Price", DbType.Decimal, column => column.WithPrecision(19).WithScale(9))
|
||||
);
|
||||
|
||||
_schemaBuilder
|
||||
.ExecuteSql(String.Format("INSERT INTO TEST_Product (Price) VALUES ({0})", "123456.123456789"));
|
||||
|
||||
var query = _session.CreateSQLQuery("SELECT MAX(Price) FROM TEST_Product");
|
||||
Assert.That(query.UniqueResult(), Is.EqualTo(123456.123456789m));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -120,6 +120,9 @@
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.SQLite">
|
||||
<HintPath>..\..\lib\sqlite\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\lib\sqlce\System.Data.SqlServerCe.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@@ -215,6 +218,8 @@
|
||||
<Compile Include="DatabaseEnabledTestsBase.cs" />
|
||||
<Compile Include="DataMigration\SchemaBuilderTests.cs" />
|
||||
<Compile Include="DataMigration\DataMigrationTests.cs" />
|
||||
<Compile Include="DataMigration\SQLite\SQLiteDataUtility.cs" />
|
||||
<Compile Include="DataMigration\SQLite\SQLiteSchemaBuilderTestsBase.cs" />
|
||||
<Compile Include="DataMigration\Utilities\NullInterpreter.cs" />
|
||||
<Compile Include="DataUtility.cs" />
|
||||
<Compile Include="Data\Builders\SessionFactoryBuilderTests.cs" />
|
||||
@@ -404,7 +409,16 @@
|
||||
<Copy SourceFiles="@(SqlCeBinariesx86)" DestinationFolder="$(OutputPath)\x86\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(SqlCeBinariesx64)" DestinationFolder="$(OutputPath)\amd64\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<Target Name="CopySQLiteBinaries">
|
||||
<ItemGroup>
|
||||
<SQLiteBinariesx86 Include="$(ProjectDir)..\..\lib\sqlite\x86\**\*" />
|
||||
<SQLiteBinariesx64 Include="$(ProjectDir)..\..\lib\sqlite\x64\**\*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(SQLiteBinariesx86)" DestinationFolder="$(OutputPath)\x86\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(SQLiteBinariesx64)" DestinationFolder="$(OutputPath)\amd64\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
<CallTarget Targets="CopySqlCeBinaries" />
|
||||
<CallTarget Targets="CopySQLiteBinaries" />
|
||||
</Target>
|
||||
</Project>
|
@@ -10,14 +10,17 @@ namespace Orchard.Alias {
|
||||
.Column<string>("Path", c => c.WithLength(2048))
|
||||
.Column<int>("Action_id")
|
||||
.Column<string>("RouteValues", c => c.Unlimited())
|
||||
.Column<string>("Source", c => c.WithLength(256)))
|
||||
.Column<string>("Source", c => c.WithLength(256))
|
||||
.Column<bool>("IsManaged", column => column.WithDefault(false))
|
||||
)
|
||||
.CreateTable("ActionRecord",
|
||||
table => table
|
||||
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
||||
.Column<string>("Area")
|
||||
.Column<string>("Controller")
|
||||
.Column<string>("Action"));
|
||||
return 1;
|
||||
.Column<string>("Action")
|
||||
);
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int UpdateFrom1() {
|
||||
|
@@ -9,6 +9,7 @@ using Orchard.Setup.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Notify;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Setup.Controllers {
|
||||
[ValidateInput(false), Themed]
|
||||
@@ -72,20 +73,18 @@ namespace Orchard.Setup.Controllers {
|
||||
|
||||
[HttpPost, ActionName("Index")]
|
||||
public ActionResult IndexPOST(SetupViewModel model) {
|
||||
// Sets the setup request timeout to 10 minutes to give enough time to execute custom recipes.
|
||||
HttpContext.Server.ScriptTimeout = 600;
|
||||
|
||||
var recipes = _setupService.Recipes().ToList();
|
||||
|
||||
// If no builtin provider, a connection string is mandatory.
|
||||
if (model.DatabaseProvider != SetupDatabaseType.Builtin && string.IsNullOrEmpty(model.DatabaseConnectionString))
|
||||
if ((model.DatabaseProvider != SetupDatabaseType.Builtin && model.DatabaseProvider != SetupDatabaseType.SQLite) && string.IsNullOrEmpty(model.DatabaseConnectionString))
|
||||
ModelState.AddModelError("DatabaseConnectionString", T("A connection string is required.").Text);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(model.ConfirmPassword) && model.AdminPassword != model.ConfirmPassword) {
|
||||
ModelState.AddModelError("ConfirmPassword", T("Password confirmation must match.").Text);
|
||||
}
|
||||
|
||||
if (model.DatabaseProvider != SetupDatabaseType.Builtin && !string.IsNullOrWhiteSpace(model.DatabaseTablePrefix)) {
|
||||
if ((model.DatabaseProvider != SetupDatabaseType.Builtin && model.DatabaseProvider != SetupDatabaseType.SQLite) && !String.IsNullOrWhiteSpace(model.DatabaseTablePrefix))
|
||||
{
|
||||
model.DatabaseTablePrefix = model.DatabaseTablePrefix.Trim();
|
||||
if (!Char.IsLetter(model.DatabaseTablePrefix[0])) {
|
||||
ModelState.AddModelError("DatabaseTablePrefix", T("The table prefix must begin with a letter.").Text);
|
||||
@@ -128,9 +127,9 @@ namespace Orchard.Setup.Controllers {
|
||||
case SetupDatabaseType.MySql:
|
||||
providerName = "MySql";
|
||||
break;
|
||||
|
||||
case SetupDatabaseType.PostgreSql:
|
||||
providerName = "PostgreSql";
|
||||
case SetupDatabaseType.SQLite:
|
||||
providerName = "SQLite";
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@@ -19,6 +19,35 @@
|
||||
var description = $(this).find(":selected").data("recipe-description"); // reads the html attribute of the selected option
|
||||
$("#recipedescription").text(description); // make the contents of <div id="recipe-description"></div> be the escaped description string
|
||||
});
|
||||
$(".data").find('input[name=DatabaseProvider]:checked').click();
|
||||
|
||||
$(".embedded").change(function() {
|
||||
alert($(this).find(":selected").attr("selected"));
|
||||
|
||||
});
|
||||
|
||||
var handleVisibility = function() {
|
||||
if ($("#sqlserver").is(":checked") || $("#mysql").is(":checked")) {
|
||||
$("#databaseDetails").show();
|
||||
|
||||
if ($("#sqlserver").is(":checked")) {
|
||||
$("#sqlserverDetails").show();
|
||||
$("#mysqlDetails").hide();
|
||||
} else {
|
||||
$("#sqlserverDetails").hide();
|
||||
$("#mysqlDetails").show();
|
||||
}
|
||||
} else {
|
||||
$("#databaseDetails").hide();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
$("input[name='DatabaseProvider']").change(handleVisibility);
|
||||
var ourClicked = $("input[name='DatabaseProvider'][checked='checked']");
|
||||
|
||||
$("input[name='DatabaseProvider']").not("[checked='checked']")[0].click();
|
||||
ourClicked.click();
|
||||
|
||||
});
|
||||
})(jQuery);
|
@@ -6,5 +6,6 @@
|
||||
SqlServer,
|
||||
MySql,
|
||||
PostgreSql,
|
||||
SQLite,
|
||||
}
|
||||
}
|
@@ -36,11 +36,11 @@
|
||||
</div>
|
||||
<div>
|
||||
<label for="AdminPassword">@T("Choose a password:")</label>
|
||||
@Html.PasswordFor(svm => svm.AdminPassword, new { @class = "text single-line" })
|
||||
@Html.PasswordFor(svm => svm.AdminPassword, new { @class = "text-box single-line" })
|
||||
</div>
|
||||
<div>
|
||||
<label for="ConfirmAdminPassword">@T("Confirm the password:")</label>
|
||||
@Html.PasswordFor(svm => svm.ConfirmPassword, new { @class = "text single-line" })
|
||||
@Html.PasswordFor(svm => svm.ConfirmPassword, new { @class = "text-box single-line" })
|
||||
</div>
|
||||
</fieldset>
|
||||
if (!Model.DatabaseIsPreconfigured) {
|
||||
@@ -48,11 +48,15 @@ if (!Model.DatabaseIsPreconfigured) {
|
||||
<legend>@T("How would you like to store your data?")</legend>
|
||||
@Html.ValidationMessage("DatabaseOptions", "Unable to setup data storage.")
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.Builtin.ToString(), new { id = "builtin" })
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.Builtin.ToString(), new { id = "builtin"})
|
||||
<label for="builtin" class="forcheckbox">@T("Use built-in data storage (SQL Server Compact)")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.SqlServer.ToString(), new { id = "sqlserver" })
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.SQLite.ToString(), new { id = "sqlite" })
|
||||
<label for="sqlite" class="forcheckbox">@T("Use an embedded SQLite database")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.SqlServer.ToString(), new { id = "sqlserver"})
|
||||
<label for="sqlserver" class="forcheckbox">@T("Use an existing SQL Server, SQL Express database")</label>
|
||||
</div>
|
||||
<div>
|
||||
@@ -63,13 +67,13 @@ if (!Model.DatabaseIsPreconfigured) {
|
||||
@Html.RadioButtonFor(svm => svm.DatabaseProvider, SetupDatabaseType.PostgreSql.ToString(), new { id = "postgresql" })
|
||||
<label for="postgresql" class="forcheckbox">@T("Use an existing PostgreSQL database")</label>
|
||||
</div>
|
||||
<div data-controllerid="builtin" data-defaultstate="hidden">
|
||||
<div>
|
||||
<label for="DatabaseConnectionString">@T("Connection string")</label>
|
||||
@Html.EditorFor(svm => svm.DatabaseConnectionString)
|
||||
<span data-controllerid="sqlserver" class="hint databaseTypeHint">
|
||||
<span class="hint databaseTypeHint" id="sqlserverDetails">
|
||||
@T("Data Source=sqlServerName;Initial Catalog=dbName;User ID=userName;Password=password")
|
||||
</span>
|
||||
<span data-controllerid="mysql" class="hint databaseTypeHint">
|
||||
<span class="hint databaseTypeHint" id="mysqlDetails">
|
||||
@T("Data Source=serverName;Database=dbName;User Id=userName;Password=password")
|
||||
</span>
|
||||
<span data-controllerid="postgresql" class="hint databaseTypeHint">
|
||||
|
@@ -87,6 +87,9 @@
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data.SQLite">
|
||||
<HintPath>..\..\lib\sqlite\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\lib\sqlce\System.Data.SqlServerCe.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@@ -275,12 +278,25 @@
|
||||
<Copy SourceFiles="@(SqlCeBinariesx86)" DestinationFolder="$(OutputPath)\x86\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(SqlCeBinariesx64)" DestinationFolder="$(OutputPath)\amd64\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<Target Name="CopySQLiteBinaries">
|
||||
<ItemGroup>
|
||||
<SQLiteBinariesx86 Include="$(ProjectDir)..\..\lib\sqlite\x86\**\*" />
|
||||
<SQLiteBinariesx64 Include="$(ProjectDir)..\..\lib\sqlite\x64\**\*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(SQLiteBinariesx86)" DestinationFolder="$(OutputPath)\x86\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="@(SQLiteBinariesx64)" DestinationFolder="$(OutputPath)\amd64\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
<Target Name="CleanSQLiteBinaries">
|
||||
<RemoveDir Directories="$(ProjectDir)\x86"/>
|
||||
<RemoveDir Directories="$(ProjectDir)\x64"/>
|
||||
</Target>
|
||||
<Target Name="AfterBuild" DependsOnTargets="MvcBuildViews">
|
||||
<PropertyGroup>
|
||||
<AreasManifestDir>$(ProjectDir)\..\Manifests</AreasManifestDir>
|
||||
</PropertyGroup>
|
||||
<CallTarget Targets="ExcludeRootBinariesDeployment" />
|
||||
<CallTarget Targets="CopySqlCeBinaries" />
|
||||
<CallTarget Targets="CopySQLiteBinaries" />
|
||||
<!-- If this is an area child project, uncomment the following line:
|
||||
<CreateAreaManifest AreaName="$(AssemblyName)" AreaType="Child" AreaPath="$(ProjectDir)" ManifestPath="$(AreasManifestDir)" ContentFiles="@(Content)" />
|
||||
-->
|
||||
@@ -289,4 +305,7 @@
|
||||
<CopyAreaManifests ManifestPath="$(AreasManifestDir)" CrossCopy="false" RenameViews="true" />
|
||||
-->
|
||||
</Target>
|
||||
<Target Name="AfterClean">
|
||||
<CallTarget Targets="CleanSQLiteBinaries"/>
|
||||
</Target>
|
||||
</Project>
|
||||
|
@@ -270,6 +270,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gulp", "Gulp", "{90EBEE36-B
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
CodeCoverage|Any CPU = CodeCoverage|Any CPU
|
||||
Coverage|Any CPU = Coverage|Any CPU
|
||||
|
20
src/Orchard/Data/Migration/Interpreters/DialectService.cs
Normal file
20
src/Orchard/Data/Migration/Interpreters/DialectService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NHibernate.Cfg;
|
||||
using NHibernate.Dialect;
|
||||
|
||||
namespace Orchard.Data.Migration.Interpreters
|
||||
{
|
||||
public interface IDialectService : IDependency {
|
||||
Dialect GetDialect(Configuration config);
|
||||
}
|
||||
|
||||
public class DialectService : IDialectService
|
||||
{
|
||||
public Dialect GetDialect(Configuration config) {
|
||||
return Dialect.GetDialect(config.Properties);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,40 +1,311 @@
|
||||
using Orchard.Data.Migration.Schema;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using NHibernate;
|
||||
using NHibernate.Dialect;
|
||||
using NHibernate.SqlTypes;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.Data.Migration.Schema;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Outercurve.SQLiteCreateTree;
|
||||
using Outercurve.SQLiteCreateTree.AlterTable;
|
||||
using Outercurve.SQLiteCreateTree.Nodes;
|
||||
using Outercurve.SQLiteCreateTree.Nodes.ColumnConstraint;
|
||||
using OcfAction = Outercurve.SQLiteCreateTree.AlterTable.Action;
|
||||
|
||||
namespace Orchard.Data.Migration.Interpreters {
|
||||
public class SQLiteCommandInterpreter :
|
||||
ICommandInterpreter<DropColumnCommand>,
|
||||
ICommandInterpreter<AlterColumnCommand>,
|
||||
ICommandInterpreter<CreateForeignKeyCommand>,
|
||||
ICommandInterpreter<DropForeignKeyCommand>,
|
||||
ICommandInterpreter<AddIndexCommand>,
|
||||
ICommandInterpreter<DropIndexCommand> {
|
||||
public class SQLiteCommandInterpreter : ICommandInterpreter<CreateTableCommand>,
|
||||
ICommandInterpreter<AlterTableCommand>,
|
||||
//ICommandInterpreter<CreateForeignKeyCommand>,
|
||||
ICommandInterpreter<DropForeignKeyCommand> {
|
||||
|
||||
public string[] CreateStatements(DropColumnCommand command) {
|
||||
return new string[0];
|
||||
|
||||
//private readonly ISession _session;
|
||||
private readonly Dialect _dialect;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
//private readonly DefaultDataMigrationInterpreter _dataMigrationInterpreter;
|
||||
|
||||
//public SQLiteCommandInterpreter(DefaultDataMigrationInterpreter dataMigrationInterpreter) {
|
||||
// _dataMigrationInterpreter = dataMigrationInterpreter;
|
||||
//}
|
||||
|
||||
public SQLiteCommandInterpreter(
|
||||
ISessionLocator locator,
|
||||
ShellSettings shellSettings,
|
||||
//ITransactionManager transactionManager,
|
||||
ISessionFactoryHolder sessionFactoryHolder,
|
||||
IDialectService dialectService
|
||||
) {
|
||||
//_session = transactionManager.GetSession();
|
||||
_shellSettings = shellSettings;
|
||||
|
||||
var configuration = sessionFactoryHolder.GetConfiguration();
|
||||
|
||||
_dialect = dialectService.GetDialect(configuration);
|
||||
}
|
||||
|
||||
public string[] CreateStatements(AlterColumnCommand command) {
|
||||
return new string[0];
|
||||
public string DataProvider {
|
||||
get { return "SQLite"; }
|
||||
}
|
||||
|
||||
public string[] CreateStatements(CreateForeignKeyCommand command) {
|
||||
return new string[0];
|
||||
public string[] CreateStatements(CreateTableCommand command) {
|
||||
var createTable = new CreateTableNode {
|
||||
TableName = PrefixTableName(command.Name), ColumnDefinitions = command.TableCommands.OfType<CreateColumnCommand>().
|
||||
Select(CreateColumnDefNode)
|
||||
.ToList()
|
||||
};
|
||||
var visitor = new TreeStringOutputVisitor();
|
||||
|
||||
string[] ret = createTable.Accept(visitor).ToString().Split(new[] {System.Environment.NewLine}, StringSplitOptions.None);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public string[] CreateStatements(DropForeignKeyCommand command) {
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
public string[] CreateStatements(AddIndexCommand command) {
|
||||
public string[] CreateStatements(AlterTableCommand command) {
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
public string[] CreateStatements(DropIndexCommand command) {
|
||||
return new string[0];
|
||||
//private IEnumerable<string> GetIndexNodesForTable(string tableName) {
|
||||
// var query = _session.CreateSQLQuery(String.Format("SELECT sql FROM sqlite_master WHERE tbl_name = '{0}' AND type = 'index'", tableName));
|
||||
// var indexStrings = query.List<string>();
|
||||
// return indexStrings;
|
||||
//}
|
||||
|
||||
//private string GetCreateTableNodeFromSession(string tableName) {
|
||||
// var query = _session.CreateSQLQuery(String.Format("SELECT sql FROM sqlite_master WHERE tbl_name = '{0}' AND type = 'table'", tableName));
|
||||
// var createString = query.UniqueResult<string>();
|
||||
// if (createString == null) {
|
||||
// // we hav ea problem
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// return createString;
|
||||
//}
|
||||
|
||||
private string PrefixTableName(string tableName) {
|
||||
return PrefixTableName(_shellSettings, tableName);
|
||||
}
|
||||
public static string PrefixTableName(ShellSettings shellSettings, string tableName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(shellSettings.DataTablePrefix))
|
||||
{
|
||||
return tableName;
|
||||
}
|
||||
return shellSettings.DataTablePrefix + "_" + tableName;
|
||||
}
|
||||
|
||||
public string DataProvider {
|
||||
get { return "SQLite"; }
|
||||
private OrchardToSQLiteAdapter CreateOrchardToSQLiteAdapter() {
|
||||
return new OrchardToSQLiteAdapter(_shellSettings, _dialect);
|
||||
}
|
||||
|
||||
private ColumnDefNode CreateColumnDefNode(CreateColumnCommand command)
|
||||
{
|
||||
var ret = new ColumnDefNode { ColumnName = command.ColumnName, ColumnConstraints = new List<ColumnConstraintNode>() };
|
||||
|
||||
//dialect converts DbType.Int16-64 to "INT" not "INTEGER" and only INTEGER columns can be autoincremented. This fixes that.
|
||||
string correctType = command.IsIdentity ? "INTEGER" : _dialect.GetTypeName(new SqlType(command.DbType));
|
||||
|
||||
ret.TypeNameNode = SQLiteParseVisitor.ParseString<TypeNameNode>(correctType, i => i.type_name());
|
||||
|
||||
//not quite right but should work
|
||||
|
||||
if (command.IsIdentity || command.IsPrimaryKey)
|
||||
{
|
||||
var primKey = new PrimaryKeyConstraintNode();
|
||||
if (command.IsIdentity)
|
||||
{
|
||||
primKey.AutoIncrement = true;
|
||||
}
|
||||
ret.ColumnConstraints.Add(primKey);
|
||||
}
|
||||
|
||||
if (command.Default != null)
|
||||
{
|
||||
ret.ColumnConstraints.Add(new DefaultConstraintNode { Value = ConvertToSqlValue(command.Default) });
|
||||
}
|
||||
|
||||
if (command.IsNotNull)
|
||||
{
|
||||
ret.ColumnConstraints.Add(new NotNullConstraintNode());
|
||||
}
|
||||
else if (command.Default == null && !command.IsPrimaryKey && !command.IsUnique)
|
||||
{
|
||||
ret.ColumnConstraints.Add(new DefaultConstraintNode { Value = "NULL" });
|
||||
}
|
||||
|
||||
if (command.IsUnique)
|
||||
{
|
||||
ret.ColumnConstraints.Add(new UniqueConstraintNode());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public string ConvertToSqlValue(object value) {
|
||||
if (value == null) {
|
||||
return "null";
|
||||
}
|
||||
|
||||
TypeCode typeCode = Type.GetTypeCode(value.GetType());
|
||||
switch (typeCode) {
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.String:
|
||||
case TypeCode.Char:
|
||||
return String.Concat("'", Convert.ToString(value).Replace("'", "''"), "'");
|
||||
case TypeCode.Boolean:
|
||||
return _dialect.ToBooleanValueString((bool)value);
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.UInt64:
|
||||
case TypeCode.Single:
|
||||
case TypeCode.Double:
|
||||
case TypeCode.Decimal:
|
||||
return Convert.ToString(value, CultureInfo.InvariantCulture);
|
||||
case TypeCode.DateTime:
|
||||
return String.Concat("'", Convert.ToString(value, CultureInfo.InvariantCulture), "'");
|
||||
}
|
||||
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class OrchardToSQLiteAdapter {
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly Dialect _dialect;
|
||||
|
||||
internal OrchardToSQLiteAdapter(ShellSettings shellSettings, Dialect dialect) {
|
||||
_shellSettings = shellSettings;
|
||||
_dialect = dialect;
|
||||
}
|
||||
|
||||
|
||||
private OcfAction.TableCommand Visit(TableCommand command) {
|
||||
if (command is AddColumnCommand) {
|
||||
return Visit(command as AddColumnCommand);
|
||||
}
|
||||
if (command is DropColumnCommand) {
|
||||
return Visit(command as DropColumnCommand);
|
||||
}
|
||||
if (command is AddIndexCommand) {
|
||||
return Visit(command as AddIndexCommand);
|
||||
}
|
||||
if (command is DropIndexCommand) {
|
||||
return Visit(command as DropIndexCommand);
|
||||
}
|
||||
|
||||
if (command is AlterColumnCommand) {
|
||||
return Visit(command as AlterColumnCommand);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public OcfAction.AlterTableCommand Visit(AlterTableCommand command) {
|
||||
var output = new OcfAction.AlterTableCommand(PrefixTableName(command.Name));
|
||||
|
||||
foreach (var tc in command.TableCommands) {
|
||||
output.TableCommands.Add(Visit(tc));
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
public OcfAction.AddColumnCommand Visit(AddColumnCommand command) {
|
||||
var output = new OcfAction.AddColumnCommand(PrefixTableName(command.TableName), command.ColumnName);
|
||||
|
||||
output.WithType(GetTypeName(command.DbType));
|
||||
|
||||
if (command.IsNotNull) {
|
||||
output.NotNull();
|
||||
}
|
||||
else {
|
||||
output.Nullable();
|
||||
}
|
||||
|
||||
|
||||
if (command.IsUnique) {
|
||||
output.Unique();
|
||||
}
|
||||
if (command.IsPrimaryKey) {
|
||||
output.PrimaryKey();
|
||||
}
|
||||
|
||||
if (command.IsIdentity) {
|
||||
output.Identity();
|
||||
}
|
||||
|
||||
output.WithDefault(command.Default);
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public OcfAction.DropColumnCommand Visit(DropColumnCommand command) {
|
||||
return new OcfAction.DropColumnCommand(PrefixTableName(command.TableName), command.ColumnName);
|
||||
}
|
||||
|
||||
public OcfAction.AlterColumnCommand Visit(AlterColumnCommand command) {
|
||||
var output = new OcfAction.AlterColumnCommand(PrefixTableName(command.TableName), command.ColumnName);
|
||||
if (command.DbType != DbType.Object) {
|
||||
output.WithType(GetTypeName(command.DbType));
|
||||
}
|
||||
output.WithDefault(command.Default);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public OcfAction.AddIndexCommand Visit(AddIndexCommand command) {
|
||||
return new OcfAction.AddIndexCommand(PrefixTableName(command.TableName), command.IndexName, command.ColumnNames);
|
||||
}
|
||||
|
||||
public OcfAction.DropIndexCommand Visit(DropIndexCommand command) {
|
||||
return new OcfAction.DropIndexCommand(PrefixTableName(command.TableName), command.IndexName);
|
||||
}
|
||||
|
||||
|
||||
public OcfAction.AlterTableCommand Visit(DropForeignKeyCommand command) {
|
||||
var output = new OcfAction.AlterTableCommand(PrefixTableName(command.SrcTable));
|
||||
output.DropForeignKey(PrefixTableName(command.Name));
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
public OcfAction.AlterTableCommand Visit(CreateForeignKeyCommand command) {
|
||||
var output = new OcfAction.AlterTableCommand(PrefixTableName(command.SrcTable));
|
||||
output.CreateForeignKey(PrefixTableName(command.Name), command.SrcColumns, PrefixTableName(command.DestTable), command.DestColumns);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private string PrefixTableName(string tableName) {
|
||||
return SQLiteCommandInterpreter.PrefixTableName(_shellSettings, tableName);
|
||||
}
|
||||
|
||||
public string GetTypeName(DbType dbType) {
|
||||
return _dialect.GetTypeName(new SqlType(dbType));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
53
src/Orchard/Data/Providers/SQLiteDataServicesProvider.cs
Normal file
53
src/Orchard/Data/Providers/SQLiteDataServicesProvider.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using FluentNHibernate.Cfg.Db;
|
||||
using FluentNHibernate.Utils;
|
||||
using NHibernate.Mapping;
|
||||
|
||||
namespace Orchard.Data.Providers
|
||||
{
|
||||
public class SQLiteDataServicesProvider : AbstractDataServicesProvider {
|
||||
private readonly string _fileName;
|
||||
private readonly string _dataFolder;
|
||||
|
||||
|
||||
public SQLiteDataServicesProvider(string dataFolder, string connectionString) {
|
||||
_dataFolder = dataFolder;
|
||||
_fileName = Path.Combine(dataFolder, "Orchard.sqlite");
|
||||
}
|
||||
|
||||
public SQLiteDataServicesProvider(string fileName) {
|
||||
_dataFolder = Path.GetDirectoryName(fileName);
|
||||
_fileName = fileName;
|
||||
|
||||
}
|
||||
|
||||
public static string ProviderName {
|
||||
get { return "SQLite"; }
|
||||
}
|
||||
|
||||
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
|
||||
SQLiteConfiguration persistence = SQLiteConfiguration.Standard;
|
||||
|
||||
if (createDatabase) {
|
||||
if (File.Exists(_fileName))
|
||||
File.Delete(_fileName);
|
||||
}
|
||||
|
||||
string localConnectionString = string.Format("Data Source='{0}'",
|
||||
_fileName);
|
||||
|
||||
if (!File.Exists(_fileName) && !string.IsNullOrEmpty(_dataFolder)) {
|
||||
Directory.CreateDirectory(_dataFolder);
|
||||
}
|
||||
|
||||
persistence = persistence.ConnectionString(localConnectionString);
|
||||
return persistence;
|
||||
}
|
||||
}
|
||||
}
|
26
src/Orchard/Data/Providers/SQLiteStatementProvider.cs
Normal file
26
src/Orchard/Data/Providers/SQLiteStatementProvider.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Orchard.Data.Providers
|
||||
{
|
||||
public class SQLiteStatementProvider : ISqlStatementProvider
|
||||
{
|
||||
public string DataProvider
|
||||
{
|
||||
get { return "SQLite"; }
|
||||
}
|
||||
|
||||
public string GetStatement(string command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "random":
|
||||
return "rand()";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -59,6 +59,9 @@
|
||||
<NoWarn>0436</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Antlr4.Runtime.v4.0">
|
||||
<HintPath>..\..\lib\antlr\Antlr4.Runtime.v4.0.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Autofac, Version=2.1.13.813, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\autofac\Autofac.dll</HintPath>
|
||||
@@ -104,6 +107,12 @@
|
||||
<Reference Include="Owin">
|
||||
<HintPath>..\..\lib\owin\Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Outercurve.SQLiteCreateTree">
|
||||
<HintPath>..\..\lib\sqlite-createsupport\Outercurve.SQLiteCreateTree.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Outercurve.SQLiteParser">
|
||||
<HintPath>..\..\lib\sqlite-createsupport\Outercurve.SQLiteParser.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
@@ -228,12 +237,15 @@
|
||||
<Compile Include="Data\DefaultSessionConfigurationEvents.cs" />
|
||||
<Compile Include="Data\DoNotMapAttribute.cs" />
|
||||
<Compile Include="Data\FetchRequest.cs" />
|
||||
<Compile Include="Data\Migration\Interpreters\DialectService.cs" />
|
||||
<Compile Include="Data\SessionConfigurationEventsWithParameters.cs" />
|
||||
<Compile Include="Data\ISessionConfigurationEventsWithParameters.cs" />
|
||||
<Compile Include="Data\Migration\Interpreters\MySqlCommandInterpreter.cs" />
|
||||
<Compile Include="Data\Providers\MySqlStatementProvider.cs" />
|
||||
<Compile Include="Data\Providers\SqlCeStatementProvider.cs" />
|
||||
<Compile Include="Data\Providers\ISqlStatementProvider.cs" />
|
||||
<Compile Include="Data\Providers\SQLiteDataServicesProvider.cs" />
|
||||
<Compile Include="Data\Providers\SQLiteStatementProvider.cs" />
|
||||
<Compile Include="Data\Providers\SqlServerStatementProvider.cs" />
|
||||
<Compile Include="Data\Providers\PostgreSqlStatementProvider.cs" />
|
||||
<Compile Include="Data\Providers\PostgreSqlDataServicesProvider.cs" />
|
||||
|
Reference in New Issue
Block a user