|
Let's summarize.
To use Oracle in Orchard the steps below should be followed:
1. Prepare database.
Execute SQL query: create sequence hibernate_sequence
2. Restrict identifiers. Oracle identifiers (table and column names) can't be greater than 30 characters.
a) Make sure that all field names for database records in custom modules are not greater than 30 chars.
b) Replace (using 'Find and Replace') ContentFieldDefinitionRecord with ContentFieldDefRecord.
Expected changes are in files:
src\Orchard.Tests.Modules\Widgets\Services\WidgetsServiceTest.cs
src\Orchard.Web\Core\Settings\Metadata\ContentDefinitionManager.cs
src\Orchard.Web\Core\Settings\Metadata\Records\ContentFieldDefinitionRecord.cs
src\Orchard.Web\Core\Settings\Metadata\Records\ContentPartFieldDefinitionRecord.cs
src\Orchard.Web\Core\Settings\Migrations.cs
src\Orchard.Core.Tests\Settings\Metadata\ContentDefinitionManagerTests.cs
c) Create an utility class to make table names shorter (in my project it’s a TableAliasGenerator with Generate function which returns unique table alias)
d) Apply TableAliasGenerator
i. Orchard.Setup.Services.SetupService.Setup function:
var tableName = TableAliasGenerator.Generate(tablePrefix + "Settings_ShellDescriptorRecord");
ii. (Orchard.Framework)Orchard.Data.Migration.Schema.SchemaBuilder. Aplly it in all statements like this:
CreateTableCommand(TableAliasGenerator.Generate(String.Concat(_formatPrefix(_featurePrefix), name)));
iii. (Orchard.Framework)Orchard.Environment.ShellBuilders.CompositionStrategy.BuildRecord function:
return new RecordBlueprint {
Type = type,
Feature = feature,
TableName = TableAliasGenerator.Generate(dataTablePrefix + extensionName + '_' + type.Name)
};
3. Make all column names in uppercase. Oracle creates columns with names as defined in a query, but when executing 'select' query Oracle makes all column names in uppercase. So any
standard Orchard columns can't be accessed in Oracle. Changes must be done in Orchard.Data.Migration.Schema.ColumnCommand:
private string columnName;
public string ColumnName
{
get { return columnName; }
set { columnName = value.ToUpper(); }
}
4. Add quotes to the key identifier. Orchard.Data.Migration.Interpreters.DefaultDataMigrationInterpreter.Visit(CreateTableCommand command) function:
builder.Append(_dialect.PrimaryKeyString) .Append(" ( ") .Append(String.Join(", ", primaryKeys.Select(key => "\"" + key + "\"").ToArray())) .Append(" )");
5. Replace NVARCHAR2 data type with VARCHAR2 in all 'create table' queries. Some columns in Orchard have type NVARCHAR2(2048) and Oracle is restricted at NVARCHAR2(2000). VARCHAR2 should be used instead of NVARCHAR2.
Add to the end of Orchard.Data.Migration.Interpreters.DefaultDataMigrationInterpreter.GetTypeName function:
if (_dialect is NHibernate.Dialect.Oracle9iDialect)
{
result = result.Replace("NVARCHAR2", "VARCHAR2");
}//result - is a return value
6. Rename (using 'Refactor->Rename') Number to Number_ in Orchard.ContentManagement.Records.ContentItemVersionRecord. And do it manually in Orchard.ContentManagement.DataMigrations.FrameworkDataMigration.
Reason:"Number" is a reserved word in OracleDB.
Expected changes are in:
Orchard.ContentManagement.Records.ContentItemVersionRecord
Orchard.ContentManagement.DataMigrations.FrameworkDataMigration
Orchard.Tests.ContentManagement.DefaultContentManagerTests
Orchard.ContentManagement.ContentItem
Orchard.ContentManagement.DefaultContentManager
7. Oracle DB doesn't support empty strings (empty == null). To workaround this changes should be done in Orchard.Alias.Implementation.Updater.AliasHolderUpdater.Refresh function:
_aliasHolder.SetAliases(aliases.Select(alias => new AliasInfo { Path = alias.Item1 ?? string.Empty, Area = alias.Item2, RouteValues = alias.Item3 }));
8. Implement data provider Orchard.Data.Providers.OracleDataServiceProvider (similar to MySqlDataServiceProvider)
9. Apply OracleDataServiceProvider
a) Add in Orchard.Setup.Index.cshtml:
<div>
@Html.RadioButtonFor(svm => svm.DatabaseProvider, Orchard.Setup.Controllers.SetupDatabaseType.Oracle.ToString(), new { id = "oracle" })
<label for="oracle" class="forcheckbox">@T("Use an existing Oracle database")</label>
</div>
b) Add 'Oracle' value to Orchard.Setup.Controllers.SetupDatabaseType enum
c) Add to Orchard.Setup.Controllers.SetupController.IndexPOST function the following code:
case SetupDatabaseType.Oracle:
providerName = "Oracle";
break;
Your suggestions? How to simplify this Oracle adaptation?
|