Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Referential integrity code in Schema

  • Loading branch information...
commit a86228784a3065ff0becf20cb5795960536b7c88 1 parent a0809d8
@markrendle authored
Showing with 1,053 additions and 94 deletions.
  1. +5 −1 Simple.Data.IntegrationTest/NaturalJoinTest.cs
  2. +2 −1  Simple.Data.SqlCe35Test/SchemaTests/DatabaseSchemaTests.cs
  3. +1 −1  Simple.Data.SqlTest/FindTests.cs
  4. +21 −5 Simple.Data.SqlTest/SchemaTests/DatabaseSchemaTests.cs
  5. +10 −2 Simple.Data/Ado/AdoAdapter.cs
  6. +2 −0  Simple.Data/Ado/FindHelper.cs
  7. +0 −3  Simple.Data/Ado/IConnectionProvider.cs
  8. +10 −0 Simple.Data/Ado/ISchemaProvider.cs
  9. +1 −1  Simple.Data/Ado/ProviderHelper.cs
  10. +79 −0 Simple.Data/Ado/SqlConnectionProvider.cs
  11. +0 −49 Simple.Data/Ado/SqlProvider.cs
  12. +93 −0 Simple.Data/Ado/SqlSchemaProvider.cs
  13. +63 −0 Simple.Data/Commands/Joiner.cs
  14. +0 −9 Simple.Data/Database.cs
  15. +2 −2 Simple.Data/DatabaseOpener.cs
  16. +17 −8 Simple.Data/DynamicRecord.cs
  17. +45 −1 Simple.Data/DynamicReference.cs
  18. +31 −0 Simple.Data/EnumerableExtensions.cs
  19. +1 −0  Simple.Data/IAdapter.cs
  20. +93 −0 Simple.Data/Properties/Resources.Designer.cs
  21. +127 −0 Simple.Data/Properties/Resources.resx
  22. +7 −0 Simple.Data/Resources/ForeignKeysSql.txt
  23. +8 −0 Simple.Data/Resources/PrimaryKeySql.txt
  24. +1 −1  Simple.Data/Schema/Column.cs
  25. +7 −7 Simple.Data/Schema/DatabaseSchema.cs
  26. +36 −0 Simple.Data/Schema/ForeignKey.cs
  27. +23 −0 Simple.Data/Schema/ForeignKeyCollection.cs
  28. +26 −0 Simple.Data/Schema/Key.cs
  29. +43 −1 Simple.Data/Schema/Table.cs
  30. +24 −2 Simple.Data/Simple.Data.csproj
  31. +275 −0 SimpleTest/sql/release/SimpleTest.sql
View
6 Simple.Data.IntegrationTest/NaturalJoinTest.cs
@@ -18,8 +18,12 @@ static Database CreateDatabase()
[TestMethod]
public void NaturalJoinCreatesCorrectCommand()
{
+ // Arrange
dynamic database = CreateDatabase();
- database.Customer.Find(database.Customer.Orders.OrderDate == new DateTime(2010, 1, 1));
+ DateTime orderDate = new DateTime(2010, 1, 1);
+ database.Customer.Find(database.Customer.Orders.OrderDate == orderDate);
+ Assert.AreEqual("select * from Customer join Orders on Customer.CustomerId = Orders.CustomerId where Orders.OrderDate = @p1", MockDatabase.Sql);
+ Assert.AreEqual(orderDate, MockDatabase.Parameters[0]);
}
}
}
View
3  Simple.Data.SqlCe35Test/SchemaTests/DatabaseSchemaTests.cs
@@ -5,6 +5,7 @@
using System.Reflection;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Simple.Data.Ado;
using Simple.Data.Schema;
namespace Simple.Data.SqlCeTest.SchemaTests
@@ -19,7 +20,7 @@ public class DatabaseSchemaTests
private static DatabaseSchema GetSchema()
{
Database db = Database.OpenFile(DatabasePath);
- return db.GetSchema();
+ return ((AdoAdapter)db.Adapter).GetSchema();
}
[TestMethod]
View
2  Simple.Data.SqlTest/FindTests.cs
@@ -16,7 +16,7 @@ public class FindTests
public void TestMethod1()
{
var provider = ProviderHelper.GetProviderByConnectionString("data source=.");
- Assert.IsInstanceOfType(provider, typeof(SqlProvider));
+ Assert.IsInstanceOfType(provider, typeof(SqlConnectionProvider));
}
[TestMethod]
View
26 Simple.Data.SqlTest/SchemaTests/DatabaseSchemaTests.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Simple.Data.Ado;
using Simple.Data.Schema;
namespace Simple.Data.SqlTest.SchemaTests
@@ -9,14 +10,10 @@ namespace Simple.Data.SqlTest.SchemaTests
[TestClass]
public class DatabaseSchemaTests
{
- private static readonly string DatabasePath = Path.Combine(
- Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Substring(8)),
- "TestDatabase.sdf");
-
private static DatabaseSchema GetSchema()
{
Database db = Database.OpenConnection(Properties.Settings.Default.ConnectionString);
- return db.GetSchema();
+ return ((AdoAdapter)db.Adapter).GetSchema();
}
[TestMethod]
@@ -34,5 +31,24 @@ public void TestColumns()
Assert.AreEqual(1, table.Columns.Count(c => c.ActualName == "Id"));
}
+ [TestMethod]
+ public void TestPrimaryKey()
+ {
+ var schema = GetSchema();
+ var table = schema.FindTable("Customers");
+ Assert.AreEqual(1, table.PrimaryKey.Length);
+ Assert.AreEqual("CustomerId", table.PrimaryKey[0]);
+ }
+
+ [TestMethod]
+ public void TestForeignKey()
+ {
+ var schema = GetSchema();
+ var table = schema.FindTable("Orders");
+ var fkey = table.ForeignKeys.Single();
+ Assert.AreEqual("CustomerId", fkey.Columns[0]);
+ Assert.AreEqual("Customers", fkey.UniqueTable);
+ Assert.AreEqual("CustomerId", fkey.UniqueColumns[0]);
+ }
}
}
View
12 Simple.Data/Ado/AdoAdapter.cs
@@ -5,6 +5,7 @@
using System.Data.SqlClient;
using System.Linq;
using System.Text;
+using Simple.Data.Schema;
namespace Simple.Data.Ado
{
@@ -12,11 +13,13 @@ internal class AdoAdapter : IAdapter
{
private readonly Database _database;
private readonly IConnectionProvider _connectionProvider;
+ private readonly ISchemaProvider _schemaProvider;
public AdoAdapter(Database database, IConnectionProvider connectionProvider)
{
_database = database;
_connectionProvider = connectionProvider;
+ _schemaProvider = new SqlSchemaProvider(_connectionProvider);
}
public IDictionary<string, object> Find(string tableName, SimpleExpression criteria)
@@ -111,12 +114,17 @@ internal DbConnection CreateConnection()
internal DataTable GetSchema(string collectionName)
{
- return _connectionProvider.GetSchema(collectionName);
+ return _schemaProvider.GetSchema(collectionName);
}
internal DataTable GetSchema(string collectionName, params string[] restrictionValues)
{
- return _connectionProvider.GetSchema(collectionName, restrictionValues);
+ return _schemaProvider.GetSchema(collectionName, restrictionValues);
+ }
+
+ internal DatabaseSchema GetSchema()
+ {
+ return new DatabaseSchema(new SqlSchemaProvider(_connectionProvider));
}
}
}
View
2  Simple.Data/Ado/FindHelper.cs
@@ -36,6 +36,8 @@ public ICommandBuilder GetFindByCommand(string tableName, SimpleExpression crite
{
_commandBuilder.Append("select * from " + tableName);
+
+
if (criteria != null)
{
_commandBuilder.Append(" where ");
View
3  Simple.Data/Ado/IConnectionProvider.cs
@@ -1,4 +1,3 @@
-using System.Data;
using System.Data.Common;
namespace Simple.Data.Ado
@@ -7,7 +6,5 @@ public interface IConnectionProvider
{
void SetConnectionString(string connectionString);
DbConnection CreateConnection();
- DataTable GetSchema(string collectionName);
- DataTable GetSchema(string collectionName, params string[] restrictionValues);
}
}
View
10 Simple.Data/Ado/ISchemaProvider.cs
@@ -0,0 +1,10 @@
+using System.Data;
+
+namespace Simple.Data.Ado
+{
+ public interface ISchemaProvider
+ {
+ DataTable GetSchema(string collectionName);
+ DataTable GetSchema(string collectionName, params string[] restrictionValues);
+ }
+}
View
2  Simple.Data/Ado/ProviderHelper.cs
@@ -12,7 +12,7 @@ class ProviderHelper
public static IConnectionProvider GetProviderByConnectionString(string connectionString)
{
- return new SqlProvider(connectionString);
+ return new SqlConnectionProvider(connectionString);
}
public static IConnectionProvider GetProviderByFilename(string filename)
View
79 Simple.Data/Ado/SqlConnectionProvider.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Data;
+using System.Data.Common;
+using System.Data.SqlClient;
+
+namespace Simple.Data.Ado
+{
+ class SqlConnectionProvider : IConnectionProvider
+ {
+ private string _connectionString;
+
+ public SqlConnectionProvider()
+ {
+
+ }
+
+ public SqlConnectionProvider(string connectionString)
+ {
+ _connectionString = connectionString;
+ }
+
+ public DbConnection CreateConnection()
+ {
+ return new SqlConnection(_connectionString);
+ }
+
+ public void SetConnectionString(string connectionString)
+ {
+ _connectionString = connectionString;
+ }
+
+ public DataTable GetSchema(string collectionName)
+ {
+ using (var cn = CreateConnection())
+ {
+ cn.Open();
+ if (collectionName.Equals("primarykeys", StringComparison.InvariantCultureIgnoreCase))
+ {
+
+ }
+ return cn.GetSchema(collectionName);
+ }
+ }
+
+ public DataTable GetSchema(string collectionName, params string[] restrictionValues)
+ {
+ using (var cn = CreateConnection())
+ {
+ cn.Open();
+ return cn.GetSchema(collectionName, restrictionValues);
+ }
+ }
+
+ private DataTable GetPrimaryKeys()
+ {
+ return SelectToDataTable(Properties.Resources.PrimaryKeySql);
+ }
+
+ private DataTable GetForeignKeys()
+ {
+ return SelectToDataTable(Properties.Resources.ForeignKeysSql);
+ }
+
+ private DataTable SelectToDataTable(string sql)
+ {
+ var dataTable = new DataTable();
+ using (var cn = CreateConnection() as SqlConnection)
+ {
+ using (var adapter = new SqlDataAdapter(sql, cn))
+ {
+ adapter.Fill(dataTable);
+ }
+ }
+
+ return dataTable;
+
+ }
+ }
+}
View
49 Simple.Data/Ado/SqlProvider.cs
@@ -1,49 +0,0 @@
-using System.Data;
-using System.Data.Common;
-using System.Data.SqlClient;
-
-namespace Simple.Data.Ado
-{
- class SqlProvider : IConnectionProvider
- {
- private string _connectionString;
-
- public SqlProvider()
- {
-
- }
-
- public SqlProvider(string connectionString)
- {
- _connectionString = connectionString;
- }
-
- public DbConnection CreateConnection()
- {
- return new SqlConnection(_connectionString);
- }
-
- public void SetConnectionString(string connectionString)
- {
- _connectionString = connectionString;
- }
-
- public DataTable GetSchema(string collectionName)
- {
- using (var cn = CreateConnection())
- {
- cn.Open();
- return cn.GetSchema(collectionName);
- }
- }
-
- public DataTable GetSchema(string collectionName, params string[] restrictionValues)
- {
- using (var cn = CreateConnection())
- {
- cn.Open();
- return cn.GetSchema(collectionName, restrictionValues);
- }
- }
- }
-}
View
93 Simple.Data/Ado/SqlSchemaProvider.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.Ado
+{
+ class SqlSchemaProvider : ISchemaProvider
+ {
+ private readonly IConnectionProvider _connectionProvider;
+
+ public SqlSchemaProvider(IConnectionProvider connectionProvider)
+ {
+ _connectionProvider = connectionProvider;
+ }
+
+ public DataTable GetSchema(string collectionName)
+ {
+ using (var cn = _connectionProvider.CreateConnection())
+ {
+ cn.Open();
+ if (collectionName.Equals("primarykeys", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return GetPrimaryKeys();
+ }
+ if (collectionName.Equals("foreignkeys", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return GetForeignKeys();
+ }
+ return cn.GetSchema(collectionName);
+ }
+ }
+
+ public DataTable GetSchema(string collectionName, params string[] restrictionValues)
+ {
+ if (collectionName.Equals("primarykeys", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return GetPrimaryKeys(restrictionValues[0]);
+ }
+ if (collectionName.Equals("foreignkeys", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return GetForeignKeys(restrictionValues[0]);
+ }
+ using (var cn = _connectionProvider.CreateConnection())
+ {
+ cn.Open();
+ return cn.GetSchema(collectionName, restrictionValues);
+ }
+ }
+
+ private DataTable GetPrimaryKeys()
+ {
+ return SelectToDataTable(Properties.Resources.PrimaryKeySql);
+ }
+
+ private DataTable GetForeignKeys()
+ {
+ return SelectToDataTable(Properties.Resources.ForeignKeysSql);
+ }
+
+ private DataTable GetPrimaryKeys(string tableName)
+ {
+ return GetPrimaryKeys().AsEnumerable()
+ .Where(
+ row => row["TABLE_NAME"].ToString().Equals(tableName, StringComparison.InvariantCultureIgnoreCase))
+ .CopyToDataTable();
+ }
+
+ private DataTable GetForeignKeys(string tableName)
+ {
+ return GetForeignKeys().AsEnumerable()
+ .Where(
+ row => row["TABLE_NAME"].ToString().Equals(tableName, StringComparison.InvariantCultureIgnoreCase))
+ .CopyToDataTable();
+ }
+
+ private DataTable SelectToDataTable(string sql)
+ {
+ var dataTable = new DataTable();
+ using (var cn = _connectionProvider.CreateConnection() as SqlConnection)
+ {
+ using (var adapter = new SqlDataAdapter(sql, cn))
+ {
+ adapter.Fill(dataTable);
+ }
+ }
+
+ return dataTable;
+ }
+ }
+}
View
63 Simple.Data/Commands/Joiner.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Simple.Data.Ado;
+
+namespace Simple.Data.Commands
+{
+ class Joiner
+ {
+ private readonly ISchemaProvider _schemaProvider;
+ private readonly ConcurrentDictionary<string, string> _done = new ConcurrentDictionary<string, string>();
+
+ public Joiner(ISchemaProvider schemaProvider)
+ {
+ if (schemaProvider == null) throw new ArgumentNullException("schemaProvider");
+ _schemaProvider = schemaProvider;
+ }
+
+ public void AddJoins(string mainTableName, CommandBuilder commandBuilder, SimpleExpression expression)
+ {
+ _done.AddOrUpdate(mainTableName, string.Empty, (s, o) => string.Empty);
+ foreach (var tablePair in GetTablePairs(expression))
+ {
+ AddJoin(tablePair.Item1, tablePair.Item2);
+ }
+ }
+
+ private void AddJoin(string table1, string table2)
+ {
+ }
+
+ private IEnumerable<Tuple<string,string>> GetTablePairs(SimpleExpression expression)
+ {
+ return GetReferencesFromExpression(expression)
+ .SelectMany(dr => dr.GetAllObjectNames().SkipLast().ToTuplePairs())
+ .Distinct();
+ }
+
+ private IEnumerable<DynamicReference> GetReferencesFromExpression(SimpleExpression expression)
+ {
+ if (expression.Type == SimpleExpressionType.And || expression.Type == SimpleExpressionType.Or)
+ {
+ return GetReferencesFromExpression((SimpleExpression) expression.LeftOperand)
+ .Concat(GetReferencesFromExpression((SimpleExpression) expression.LeftOperand));
+ }
+
+ var result = Enumerable.Empty<DynamicReference>();
+
+ if (expression.LeftOperand is DynamicReference)
+ {
+ result = result.Concat(new[] {(DynamicReference) expression.LeftOperand});
+ }
+ if (expression.RightOperand is DynamicReference)
+ {
+ result = result.Concat(new[] { (DynamicReference)expression.RightOperand });
+ }
+
+ return result;
+ }
+ }
+}
View
9 Simple.Data/Database.cs
@@ -108,14 +108,5 @@ private bool NewDynamicTable(GetMemberBinder binder, out object result)
result = new DynamicTable(binder.Name, this);
return true;
}
-
- /// <summary>
- /// Gets the schema.
- /// </summary>
- /// <returns></returns>
- internal DatabaseSchema GetSchema()
- {
- return new DatabaseSchema(this);
- }
}
}
View
4 Simple.Data/DatabaseOpener.cs
@@ -54,7 +54,7 @@ public static void UseMockAdapter(Func<IAdapter> adapterCreator)
private static Database OpenDefaultMethod()
{
- return new Database(new SqlProvider(Settings.Default.ConnectionString));
+ return new Database(new SqlConnectionProvider(Settings.Default.ConnectionString));
}
private static Database OpenFileMethod(string filename)
@@ -64,7 +64,7 @@ private static Database OpenFileMethod(string filename)
private static Database OpenConnectionMethod(string connectionString)
{
- return new Database(new SqlProvider(connectionString));
+ return new Database(new SqlConnectionProvider(connectionString));
}
}
}
View
25 Simple.Data/DynamicRecord.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Reflection;
using System.Text;
+using Simple.Data.Ado;
using Simple.Data.Schema;
using System.Data;
@@ -69,11 +70,15 @@ private bool TryGetJoinResults(string name, out object result)
private bool TryGetMaster(string name, out object result)
{
- var masterJoin = _database.GetSchema().FindTable(_tableName).GetMaster(name);
- if (masterJoin != null)
+ var adoAdapter = _database.Adapter as AdoAdapter;
+ if (adoAdapter != null)
{
- result = GetMaster(masterJoin);
- return true;
+ var masterJoin = adoAdapter.GetSchema().FindTable(_tableName).GetMaster(name);
+ if (masterJoin != null)
+ {
+ result = GetMaster(masterJoin);
+ return true;
+ }
}
result = null;
return false;
@@ -83,11 +88,15 @@ private bool TryGetDetail(string name, out object result)
{
if (_tableName != null)
{
- var detailJoin = _database.GetSchema().FindTable(_tableName).GetDetail(name);
- if (detailJoin != null)
+ var adoAdapter = _database.Adapter as AdoAdapter;
+ if (adoAdapter != null)
{
- result = GetDetail(detailJoin);
- return true;
+ var detailJoin = adoAdapter.GetSchema().FindTable(_tableName).GetDetail(name);
+ if (detailJoin != null)
+ {
+ result = GetDetail(detailJoin);
+ return true;
+ }
}
}
result = null;
View
46 Simple.Data/DynamicReference.cs
@@ -7,7 +7,7 @@
namespace Simple.Data
{
- public class DynamicReference : DynamicObject
+ public class DynamicReference : DynamicObject, IEquatable<DynamicReference>
{
private readonly string _name;
private readonly DynamicReference _owner;
@@ -83,5 +83,49 @@ public static DynamicReference FromStrings(params string[] source)
{
return new SimpleExpression(column, value, SimpleExpressionType.GreaterThanOrEqual);
}
+
+ /// <summary>
+ /// Indicates whether the current object is equal to another object of the same type.
+ /// </summary>
+ /// <returns>
+ /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
+ /// </returns>
+ /// <param name="other">An object to compare with this object.</param>
+ public bool Equals(DynamicReference other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Equals(other._name, _name) && Equals(other._owner, _owner);
+ }
+
+ /// <summary>
+ /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
+ /// </summary>
+ /// <returns>
+ /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
+ /// </returns>
+ /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. </param><filterpriority>2</filterpriority>
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof (DynamicReference)) return false;
+ return Equals((DynamicReference) obj);
+ }
+
+ /// <summary>
+ /// Serves as a hash function for a particular type.
+ /// </summary>
+ /// <returns>
+ /// A hash code for the current <see cref="T:System.Object"/>.
+ /// </returns>
+ /// <filterpriority>2</filterpriority>
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((_name != null ? _name.GetHashCode() : 0)*397) ^ (!ReferenceEquals(_owner, null) ? _owner.GetHashCode() : 0);
+ }
+ }
}
}
View
31 Simple.Data/EnumerableExtensions.cs
@@ -43,5 +43,36 @@ public static T BestMatchOrDefault<T>(this IEnumerable<T> source, params Func<T,
{
return source.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
+
+ public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source)
+ {
+ var buffer = default(T);
+ var enumerator = source.GetEnumerator();
+ if (enumerator.MoveNext())
+ {
+ buffer = enumerator.Current;
+ }
+ while (enumerator.MoveNext())
+ {
+ yield return buffer;
+ buffer = enumerator.Current;
+ }
+ }
+
+ public static IEnumerable<Tuple<T,T>> ToTuplePairs<T>(this IEnumerable<T> source)
+ {
+ var buffer = default(T);
+ var enumerator = source.GetEnumerator();
+ if (enumerator.MoveNext())
+ {
+ buffer = enumerator.Current;
+ }
+ while (enumerator.MoveNext())
+ {
+ yield return Tuple.Create(buffer, enumerator.Current);
+ buffer = enumerator.Current;
+ }
+
+ }
}
}
View
1  Simple.Data/IAdapter.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using Simple.Data.Schema;
namespace Simple.Data
{
View
93 Simple.Data/Properties/Resources.Designer.cs
@@ -0,0 +1,93 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.1
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Simple.Data.Properties {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Simple.Data.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to select fkcu.TABLE_SCHEMA, fkcu.TABLE_NAME, fkcu.COLUMN_NAME,
+ ///pkcu.TABLE_SCHEMA AS UNIQUE_TABLE_SCHEMA, pkcu.TABLE_NAME AS UNIQUE_TABLE_NAME, pkcu.COLUMN_NAME AS UNIQUE_COLUMN_NAME
+ ///FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
+ ///JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE fkcu ON rc.CONSTRAINT_NAME = fkcu.CONSTRAINT_NAME
+ ///JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE pkcu ON rc.CONSTRAINT_NAME = pkcu.CONSTRAINT_NAME
+ ///WHERE fkcu.ORDINAL_POSITION = pkcu.ORDINAL_POSITION.
+ /// </summary>
+ internal static string ForeignKeysSql {
+ get {
+ return ResourceManager.GetString("ForeignKeysSql", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to select kcu.TABLE_SCHEMA, kcu.TABLE_NAME, kcu.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.COLUMN_NAME, kcu.ORDINAL_POSITION
+ /// from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
+ /// join INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
+ /// on kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
+ /// and kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
+ /// and kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
+ /// and kcu.TABLE_NAME = tc.TABLE_NAME
+ /// where tc.CONSTRAINT_TYPE = &apos;PRIMARY KEY&apos;.
+ /// </summary>
+ internal static string PrimaryKeySql {
+ get {
+ return ResourceManager.GetString("PrimaryKeySql", resourceCulture);
+ }
+ }
+ }
+}
View
127 Simple.Data/Properties/Resources.resx
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="ForeignKeysSql" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\resources\foreignkeyssql.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+ </data>
+ <data name="PrimaryKeySql" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>..\Resources\PrimaryKeySql.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+ </data>
+</root>
View
7 Simple.Data/Resources/ForeignKeysSql.txt
@@ -0,0 +1,7 @@
+select fkcu.TABLE_SCHEMA, fkcu.TABLE_NAME, fkcu.COLUMN_NAME,
+pkcu.TABLE_SCHEMA AS UNIQUE_TABLE_SCHEMA, pkcu.TABLE_NAME AS UNIQUE_TABLE_NAME, pkcu.COLUMN_NAME AS UNIQUE_COLUMN_NAME,
+fkcu.ORDINAL_POSITION
+FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
+JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE fkcu ON rc.CONSTRAINT_NAME = fkcu.CONSTRAINT_NAME
+JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE pkcu ON rc.UNIQUE_CONSTRAINT_NAME = pkcu.CONSTRAINT_NAME
+WHERE fkcu.ORDINAL_POSITION = pkcu.ORDINAL_POSITION
View
8 Simple.Data/Resources/PrimaryKeySql.txt
@@ -0,0 +1,8 @@
+select kcu.TABLE_SCHEMA, kcu.TABLE_NAME, kcu.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.COLUMN_NAME, kcu.ORDINAL_POSITION
+ from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
+ join INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
+ on kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
+ and kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
+ and kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
+ and kcu.TABLE_NAME = tc.TABLE_NAME
+ where tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
View
2  Simple.Data/Schema/Column.cs
@@ -30,7 +30,7 @@ public string ActualName
public static IEnumerable<Column> GetColumnsForTable(Table table)
{
- var columns = ((AdoAdapter)table.DatabaseSchema.Database.Adapter).GetSchema("Columns", null, table.Schema, table.ActualName);
+ var columns = table.DatabaseSchema.SchemaProvider.GetSchema("Columns", null, table.Schema, table.ActualName);
return columns.AsEnumerable().Select(row => new Column(row["column_name"].ToString()));
}
View
14 Simple.Data/Schema/DatabaseSchema.cs
@@ -10,23 +10,23 @@ namespace Simple.Data.Schema
{
internal class DatabaseSchema
{
- private readonly Database _database;
+ private readonly ISchemaProvider _schemaProvider;
private readonly Lazy<TableCollection> _lazyTables;
- public DatabaseSchema(Database database)
+ public DatabaseSchema(ISchemaProvider schemaProvider)
{
_lazyTables = new Lazy<TableCollection>(CreateTableCollection);
- _database = database;
+ _schemaProvider = schemaProvider;
}
- public Database Database
+ public ISchemaProvider SchemaProvider
{
- get { return _database; }
+ get { return _schemaProvider; }
}
public bool IsAvailable
{
- get { return _database != null; }
+ get { return _schemaProvider != null; }
}
public IEnumerable<Table> Tables
@@ -41,7 +41,7 @@ public Table FindTable(string tableName)
private TableCollection CreateTableCollection()
{
- var table = ((AdoAdapter) _database.Adapter).GetSchema("Tables");
+ var table = _schemaProvider.GetSchema("Tables");
var query = table.AsEnumerable().Select(
row =>
View
36 Simple.Data/Schema/ForeignKey.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.Schema
+{
+ class ForeignKey
+ {
+ private readonly Key _columns;
+ private readonly string _uniqueTable;
+ private readonly Key _uniqueColumns;
+
+ public ForeignKey(string[] columns, string uniqueTable, string[] uniqueColumns)
+ {
+ _columns = new Key(columns);
+ _uniqueTable = uniqueTable;
+ _uniqueColumns = new Key(uniqueColumns);
+ }
+
+ public Key UniqueColumns
+ {
+ get { return _uniqueColumns; }
+ }
+
+ public Key Columns
+ {
+ get { return _columns; }
+ }
+
+ public string UniqueTable
+ {
+ get { return _uniqueTable; }
+ }
+ }
+}
View
23 Simple.Data/Schema/ForeignKeyCollection.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.Schema
+{
+ class ForeignKeyCollection : KeyedCollection<string, ForeignKey>
+ {
+ /// <summary>
+ /// When implemented in a derived class, extracts the key from the specified element.
+ /// </summary>
+ /// <returns>
+ /// The key for the specified element.
+ /// </returns>
+ /// <param name="item">The element from which to extract the key.</param>
+ protected override string GetKeyForItem(ForeignKey item)
+ {
+ return item.UniqueTable;
+ }
+ }
+}
View
26 Simple.Data/Schema/Key.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Simple.Data.Schema
+{
+ class Key
+ {
+ private readonly string[] _columns;
+ public Key(string[] columns)
+ {
+ _columns = columns;
+ }
+
+ public string this[int index]
+ {
+ get { return _columns[index]; }
+ }
+
+ public int Length
+ {
+ get { return _columns.Length; }
+ }
+ }
+}
View
44 Simple.Data/Schema/Table.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Data;
using System.Linq;
using System.Text;
@@ -13,6 +14,8 @@ class Table
private readonly TableType _type;
private readonly DatabaseSchema _databaseSchema;
private readonly Lazy<ColumnCollection> _lazyColumns;
+ private readonly Lazy<Key> _lazyPrimaryKey;
+ private readonly Lazy<ForeignKeyCollection> _lazyForeignKeys;
public Table(string name, string schema, string type, DatabaseSchema databaseSchema)
{
@@ -24,9 +27,11 @@ public Table(string name, string schema, string type, DatabaseSchema databaseSch
? TableType.Table
: TableType.View;
_lazyColumns = new Lazy<ColumnCollection>(GetColumns);
+ _lazyPrimaryKey = new Lazy<Key>(GetPrimaryKey);
+ _lazyForeignKeys = new Lazy<ForeignKeyCollection>(GetForeignKeys);
}
- public TableType Type1
+ public TableType Type
{
get { return _type; }
}
@@ -61,11 +66,48 @@ public Column FindColumn(string columnName)
return _lazyColumns.Value.Find(columnName);
}
+ public Key PrimaryKey
+ {
+ get { return _lazyPrimaryKey.Value; }
+ }
+
+ public ForeignKeyCollection ForeignKeys
+ {
+ get { return _lazyForeignKeys.Value; }
+ }
+
private ColumnCollection GetColumns()
{
return new ColumnCollection(Column.GetColumnsForTable(this));
}
+ private Key GetPrimaryKey()
+ {
+ var columns = _databaseSchema.SchemaProvider.GetSchema("PrimaryKeys", ActualName).AsEnumerable()
+ .OrderBy(row => (int) row["ORDINAL_POSITION"])
+ .Select(row => row["COLUMN_NAME"].ToString())
+ .ToArray();
+
+ return new Key(columns);
+ }
+
+ private ForeignKeyCollection GetForeignKeys()
+ {
+ var collection = new ForeignKeyCollection();
+
+ var keys = _databaseSchema.SchemaProvider.GetSchema("ForeignKeys", ActualName).AsEnumerable()
+ .GroupBy(row => row["UNIQUE_TABLE_NAME"].ToString());
+
+ foreach (var key in keys)
+ {
+ var columns = key.OrderBy(row => (int)row["ORDINAL_POSITION"]).Select(row => row["COLUMN_NAME"].ToString()).ToArray();
+ var uniqueColumns = key.OrderBy(row => (int)row["ORDINAL_POSITION"]).Select(row => row["UNIQUE_COLUMN_NAME"].ToString()).ToArray();
+ collection.Add(new ForeignKey(columns, key.Key, uniqueColumns));
+ }
+
+ return collection;
+ }
+
public TableJoin GetMaster(string name)
{
var master = DatabaseSchema.FindTable(name);
View
26 Simple.Data/Simple.Data.csproj
@@ -58,9 +58,12 @@
<Compile Include="Ado\ExpressionFormatter.cs" />
<Compile Include="Ado\ICommandBuilder.cs" />
<Compile Include="Ado\IExpressionFormatter.cs" />
+ <Compile Include="Ado\ISchemaProvider.cs" />
+ <Compile Include="Ado\SqlSchemaProvider.cs" />
<Compile Include="BinderHelper.cs" />
<Compile Include="Ado\CommandHelper.cs" />
<Compile Include="Commands\CommandFactory.cs" />
+ <Compile Include="Commands\Joiner.cs" />
<Compile Include="ExpressionHelper.cs" />
<Compile Include="Commands\FindAllCommand.cs" />
<Compile Include="Commands\FindCommand.cs" />
@@ -81,6 +84,11 @@
<Compile Include="Commands\InsertCommand.cs" />
<Compile Include="Commands\DeleteCommand.cs" />
<Compile Include="MethodNameParser.cs" />
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
@@ -92,12 +100,15 @@
<Compile Include="Schema\Column.cs" />
<Compile Include="Schema\ColumnCollection.cs" />
<Compile Include="Schema\DatabaseSchema.cs" />
+ <Compile Include="Schema\ForeignKey.cs" />
+ <Compile Include="Schema\ForeignKeyCollection.cs" />
+ <Compile Include="Schema\Key.cs" />
<Compile Include="Schema\SchemaSpecificStringExtensions.cs" />
<Compile Include="Schema\Table.cs" />
<Compile Include="Schema\TableCollection.cs" />
<Compile Include="Schema\TableJoin.cs" />
<Compile Include="Ado\IConnectionProvider.cs" />
- <Compile Include="Ado\SqlProvider.cs" />
+ <Compile Include="Ado\SqlConnectionProvider.cs" />
<Compile Include="Schema\TableType.cs" />
<Compile Include="SimpleExpression.cs" />
<Compile Include="SimpleExpressionType.cs" />
@@ -113,7 +124,18 @@
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
- <ItemGroup />
+ <ItemGroup>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\PrimaryKeySql.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\ForeignKeysSql.txt" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
View
275 SimpleTest/sql/release/SimpleTest.sql
@@ -0,0 +1,275 @@
+/*
+Deployment script for SimpleTest
+*/
+
+GO
+SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON;
+
+SET NUMERIC_ROUNDABORT OFF;
+
+
+GO
+:setvar DatabaseName "SimpleTest"
+:setvar DefaultDataPath ""
+:setvar DefaultLogPath ""
+
+GO
+USE [master]
+
+GO
+:on error exit
+GO
+IF (DB_ID(N'$(DatabaseName)') IS NOT NULL
+ AND DATABASEPROPERTYEX(N'$(DatabaseName)','Status') <> N'ONLINE')
+BEGIN
+ RAISERROR(N'The state of the target database, %s, is not set to ONLINE. To deploy to this database, its state must be set to ONLINE.', 16, 127,N'$(DatabaseName)') WITH NOWAIT
+ RETURN
+END
+
+GO
+IF (DB_ID(N'$(DatabaseName)') IS NOT NULL)
+BEGIN
+ ALTER DATABASE [$(DatabaseName)]
+ SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
+ DROP DATABASE [$(DatabaseName)];
+END
+
+GO
+PRINT N'Creating $(DatabaseName)...'
+GO
+CREATE DATABASE [$(DatabaseName)] COLLATE SQL_Latin1_General_CP1_CI_AS
+GO
+EXECUTE sp_dbcmptlevel [$(DatabaseName)], 100;
+
+
+GO
+IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ ALTER DATABASE [$(DatabaseName)]
+ SET ANSI_NULLS ON,
+ ANSI_PADDING ON,
+ ANSI_WARNINGS ON,
+ ARITHABORT ON,
+ CONCAT_NULL_YIELDS_NULL ON,
+ NUMERIC_ROUNDABORT OFF,
+ QUOTED_IDENTIFIER ON,
+ ANSI_NULL_DEFAULT ON,
+ CURSOR_DEFAULT LOCAL,
+ RECOVERY FULL,
+ CURSOR_CLOSE_ON_COMMIT OFF,
+ AUTO_CREATE_STATISTICS ON,
+ AUTO_SHRINK OFF,
+ AUTO_UPDATE_STATISTICS ON,
+ RECURSIVE_TRIGGERS OFF
+ WITH ROLLBACK IMMEDIATE;
+ ALTER DATABASE [$(DatabaseName)]
+ SET AUTO_CLOSE OFF
+ WITH ROLLBACK IMMEDIATE;
+ END
+
+
+GO
+IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ ALTER DATABASE [$(DatabaseName)]
+ SET ALLOW_SNAPSHOT_ISOLATION OFF;
+ END
+
+
+GO
+IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ ALTER DATABASE [$(DatabaseName)]
+ SET READ_COMMITTED_SNAPSHOT OFF;
+ END
+
+
+GO
+IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ ALTER DATABASE [$(DatabaseName)]
+ SET AUTO_UPDATE_STATISTICS_ASYNC OFF,
+ PAGE_VERIFY NONE,
+ DATE_CORRELATION_OPTIMIZATION OFF,
+ DISABLE_BROKER,
+ PARAMETERIZATION SIMPLE,
+ SUPPLEMENTAL_LOGGING OFF
+ WITH ROLLBACK IMMEDIATE;
+ END
+
+
+GO
+IF IS_SRVROLEMEMBER(N'sysadmin') = 1
+ BEGIN
+ IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ EXECUTE sp_executesql N'ALTER DATABASE [$(DatabaseName)]
+ SET TRUSTWORTHY OFF,
+ DB_CHAINING OFF
+ WITH ROLLBACK IMMEDIATE';
+ END
+ END
+ELSE
+ BEGIN
+ PRINT N'The database settings cannot be modified. You must be a SysAdmin to apply these settings.';
+ END
+
+
+GO
+IF IS_SRVROLEMEMBER(N'sysadmin') = 1
+ BEGIN
+ IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ EXECUTE sp_executesql N'ALTER DATABASE [$(DatabaseName)]
+ SET HONOR_BROKER_PRIORITY OFF
+ WITH ROLLBACK IMMEDIATE';
+ END
+ END
+ELSE
+ BEGIN
+ PRINT N'The database settings cannot be modified. You must be a SysAdmin to apply these settings.';
+ END
+
+
+GO
+USE [$(DatabaseName)]
+
+GO
+IF fulltextserviceproperty(N'IsFulltextInstalled') = 1
+ EXECUTE sp_fulltext_database 'enable';
+
+
+GO
+/*
+ Pre-Deployment Script Template
+--------------------------------------------------------------------------------------
+ This file contains SQL statements that will be executed before the build script.
+ Use SQLCMD syntax to include a file in the pre-deployment script.
+ Example: :r .\myfile.sql
+ Use SQLCMD syntax to reference a variable in the pre-deployment script.
+ Example: :setvar TableName MyTable
+ SELECT * FROM [$(TableName)]
+--------------------------------------------------------------------------------------
+*/
+
+GO
+PRINT N'Creating [dbo].[Customers]...';
+
+
+GO
+CREATE TABLE [dbo].[Customers] (
+ [CustomerId] INT IDENTITY (1, 1) NOT NULL,
+ [Name] NVARCHAR (100) NOT NULL,
+ [Address] NVARCHAR (200) NULL
+);
+
+
+GO
+PRINT N'Creating [dbo].[Items]...';
+
+
+GO
+CREATE TABLE [dbo].[Items] (
+ [ItemId] INT IDENTITY (1, 1) NOT NULL,
+ [Name] NVARCHAR (100) NOT NULL,
+ [Price] MONEY NOT NULL
+);
+
+
+GO
+PRINT N'Creating [dbo].[OrderItems]...';
+
+
+GO
+CREATE TABLE [dbo].[OrderItems] (
+ [OrderItemId] INT IDENTITY (1, 1) NOT NULL,
+ [OrderId] INT NOT NULL,
+ [ItemId] INT NOT NULL,
+ [Quantity] INT NOT NULL
+);
+
+
+GO
+PRINT N'Creating [dbo].[Orders]...';
+
+
+GO
+CREATE TABLE [dbo].[Orders] (
+ [OrderId] INT IDENTITY (1, 1) NOT NULL,
+ [OrderDate] DATETIME NOT NULL,
+ [CustomerId] INT NOT NULL
+);
+
+
+GO
+PRINT N'Creating [dbo].[Users]...';
+
+
+GO
+CREATE TABLE [dbo].[Users] (
+ [Id] INT IDENTITY (1, 1) NOT NULL,
+ [Name] NVARCHAR (100) NOT NULL,
+ [Password] NVARCHAR (100) NOT NULL,
+ [Age] INT NOT NULL
+);
+
+
+GO
+-- Refactoring step to update target server with deployed transaction logs
+CREATE TABLE [dbo].[__RefactorLog] (OperationKey UNIQUEIDENTIFIER NOT NULL PRIMARY KEY)
+GO
+sp_addextendedproperty N'microsoft_database_tools_support', N'refactoring log', N'schema', N'dbo', N'table', N'__RefactorLog'
+GO
+
+GO
+/*
+Post-Deployment Script Template
+--------------------------------------------------------------------------------------
+ This file contains SQL statements that will be appended to the build script.
+ Use SQLCMD syntax to include a file in the post-deployment script.
+ Example: :r .\myfile.sql
+ Use SQLCMD syntax to reference a variable in the post-deployment script.
+ Example: :setvar TableName MyTable
+ SELECT * FROM [$(TableName)]
+--------------------------------------------------------------------------------------
+*/
+
+GO
+IF EXISTS (SELECT 1
+ FROM [master].[dbo].[sysdatabases]
+ WHERE [name] = N'$(DatabaseName)')
+ BEGIN
+ DECLARE @VarDecimalSupported AS BIT;
+ SELECT @VarDecimalSupported = 0;
+ IF ((ServerProperty(N'EngineEdition') = 3)
+ AND (((@@microsoftversion / power(2, 24) = 9)
+ AND (@@microsoftversion & 0xffff >= 3024))
+ OR ((@@microsoftversion / power(2, 24) = 10)
+ AND (@@microsoftversion & 0xffff >= 1600))))
+ SELECT @VarDecimalSupported = 1;
+ IF (@VarDecimalSupported > 0)
+ BEGIN
+ EXECUTE sp_db_vardecimal_storage_format N'$(DatabaseName)', 'ON';
+ END
+ END
+
+
+GO
+ALTER DATABASE [$(DatabaseName)]
+ SET MULTI_USER
+ WITH ROLLBACK IMMEDIATE;
+
+
+GO
Please sign in to comment.
Something went wrong with that request. Please try again.