Imported Upstream version 5.18.0.142

Former-commit-id: 7467d4b717762eeaf652d77f1486dd11ffb1ff1f
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-09 08:20:59 +00:00
parent e52655b4dc
commit 0abdbe5a7d
1547 changed files with 93792 additions and 47893 deletions

View File

@@ -1,160 +0,0 @@
#region MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace DbLinq.Linq.Data.Sugar.Expressions
{
/// <summary>
/// Represents a GROUP BY
/// </summary>
[DebuggerDisplay("GroupByExpression {Name} (as {Alias})")]
public class GroupByExpression : TableExpression
{
public new const ExpressionType ExpressionType = (ExpressionType)CustomExpressionType.GroupBy;
public ColumnExpression SimpleGroup { get; private set; }
public IDictionary<MemberInfo, ColumnExpression> MultipleGroup { get; private set; }
public Expression KeyExpression { get; private set; }
public TableExpression Table { get; set; }
protected bool HasKey { get; private set; }
public GroupByExpression(ColumnExpression simpleGroup, Expression keyExpression)
: base(ExpressionType, simpleGroup.Table)
{
SimpleGroup = simpleGroup;
HasKey = false;
KeyExpression = keyExpression;
Table = SimpleGroup.Table;
}
public GroupByExpression(IDictionary<MemberInfo, ColumnExpression> multipleGroup, Expression keyExpression)
: base(ExpressionType, multipleGroup.Values.First().Table)
{
MultipleGroup = new Dictionary<MemberInfo, ColumnExpression>(multipleGroup);
HasKey = true;
KeyExpression = keyExpression;
Table = MultipleGroup.Values.First().Table;
}
private GroupByExpression(TableExpression tableExpression)
: base(ExpressionType, tableExpression)
{
Table = tableExpression;
}
/// <summary>
/// Returns the request member.
/// For a MultipleGroup case, we return a modified copy of the current expression
/// this copy we be called again with the final MemberInfo
/// </summary>
/// <param name="memberInfo"></param>
/// <returns></returns>
public Expression GetMember(MemberInfo memberInfo)
{
// simple groupe case here, we accept only one request: the "Key"
if (SimpleGroup != null)
{
if (IsKeyRequest(memberInfo))
{
return SimpleGroup;
}
throw Error.BadArgument("S0077: Unknown member '{0}' for simple GroupByExpression", memberInfo.Name);
}
// multiple group, we accept only Key at first time, then try any request
if (HasKey)
{
if (IsKeyRequest(memberInfo))
{
return GetKey();
}
throw Error.BadArgument("S0087: Only 'Key' member can be requested here", memberInfo.Name);
}
ColumnExpression member;
if (!MultipleGroup.TryGetValue(memberInfo, out member))
throw Error.BadArgument("S0091: Unknown member '{0}' for multiple GroupByExpression", memberInfo.Name);
return member;
}
/// <summary>
/// The only member a IGrouping has is the "Key", and we're accepting only this one at the beginning
/// </summary>
/// <param name="memberInfo"></param>
/// <returns></returns>
protected virtual bool IsKeyRequest(MemberInfo memberInfo)
{
return memberInfo.Name == "Key";
}
public GroupByExpression GetKey()
{
var newGroupBy = new GroupByExpression(Table)
{
SimpleGroup = SimpleGroup,
MultipleGroup = MultipleGroup,
HasKey = false,
Table = Table,
KeyExpression = KeyExpression,
};
return newGroupBy;
}
public IEnumerable<ColumnExpression> Columns
{
get
{
if (SimpleGroup != null)
yield return SimpleGroup;
else
{
foreach (var column in MultipleGroup.Values)
yield return column;
}
}
}
#region Expression mutation
public override Expression Mutate(IList<Expression> newOperands)
{
return this;
}
public override IEnumerable<Expression> Operands
{
get
{
yield break;
}
}
#endregion
}
}

View File

@@ -1,107 +0,0 @@
#region MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace DbLinq.Linq.Data.Sugar.Expressions
{
/// <summary>
/// ScopeExpression describes a selection.
/// It can be present at top-level or as subexpressions
/// </summary>
public class ScopeExpression : OperandsMutableExpression
{
public const ExpressionType ExpressionType = (ExpressionType)CustomExpressionType.Scope;
// Involved entities
public IList<TableExpression> Tables { get; private set; }
public IList<ColumnExpression> Columns { get; private set; }
// Clauses
public string ExecuteMethodName { get; set; } // for Execute<> calls, this member is filled with the method name
public LambdaExpression SelectExpression { get; set; } // Func<IDataRecord,T> --> creates an object from data record
public IList<Expression> Where { get; private set; }
public IList<OrderByExpression> OrderBy { get; private set; }
public IList<GroupExpression> Group { get; private set; }
public Expression Offset { get; set; }
public Expression Limit { get; set; }
public Expression OffsetAndLimit { get; set; }
// Parent scope: we will climb up to find if we don't find the request table in the current scope
public ScopeExpression Parent { get; private set; }
public ScopeExpression()
: base(ExpressionType, null, null)
{
Tables = new List<TableExpression>();
Columns = new List<ColumnExpression>();
// Local clauses
Where = new List<Expression>();
OrderBy = new List<OrderByExpression>();
Group = new List<GroupExpression>();
}
public ScopeExpression(ScopeExpression parentScopePiece)
: base(ExpressionType, null, null)
{
Parent = parentScopePiece;
// Tables and columns are empty, since the table/column lookup recurses to parentScopePiece
Tables = new List<TableExpression>();
Columns = new List<ColumnExpression>();
// Local clauses
Where = new List<Expression>();
OrderBy = new List<OrderByExpression>();
Group = new List<GroupExpression>();
}
private ScopeExpression(Type type, IList<Expression> operands)
: base(ExpressionType, type, operands)
{
}
protected override Expression Mutate2(IList<Expression> newOperands)
{
Type type;
if (newOperands.Count > 0)
type = newOperands[0].Type;
else
type = Type;
var scopeExpression = new ScopeExpression(type, newOperands);
scopeExpression.Tables = Tables;
scopeExpression.Columns = Columns;
scopeExpression.Where = Where;
scopeExpression.OrderBy = OrderBy;
scopeExpression.Group = Group;
scopeExpression.Parent = Parent;
scopeExpression.ExecuteMethodName = ExecuteMethodName;
scopeExpression.Limit = Limit;
scopeExpression.Offset = Offset;
scopeExpression.OffsetAndLimit = OffsetAndLimit;
return scopeExpression;
}
}
}

View File

@@ -1,242 +0,0 @@
//
// EntitySet.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2008 Novell, Inc.
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
namespace System.Data.Linq
{
public sealed class EntitySet<TEntity> : IList, ICollection, IList<TEntity>, ICollection<TEntity>, IEnumerable<TEntity>, IEnumerable, IListSource where TEntity : class
{
public EntitySet ()
{
}
[MonoTODO]
public EntitySet (Action<TEntity> onAdd, Action<TEntity> onRemove)
{
throw new NotImplementedException ();
}
public event ListChangedEventHandler ListChanged;
[MonoTODO]
public void Add (TEntity entity)
{
throw new NotImplementedException ();
}
[MonoTODO]
int IList.Add (object value)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void AddRange (IEnumerable<TEntity> collection)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void Assign (IEnumerable<TEntity> entitySource)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void Clear ()
{
throw new NotImplementedException ();
}
[MonoTODO]
public bool Contains (TEntity entity)
{
throw new NotImplementedException ();
}
[MonoTODO]
bool IList.Contains (object value)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void CopyTo (TEntity [] array, int arrayIndex)
{
throw new NotImplementedException ();
}
[MonoTODO]
void ICollection.CopyTo (Array array, int index)
{
throw new NotImplementedException ();
}
[MonoTODO]
public IEnumerator<TEntity> GetEnumerator ()
{
throw new NotImplementedException ();
}
[MonoTODO]
IEnumerator IEnumerable.GetEnumerator ()
{
throw new NotImplementedException ();
}
[MonoTODO]
IList IListSource.GetList ()
{
throw new NotImplementedException ();
}
[MonoTODO]
public IBindingList GetNewBindingList ()
{
throw new NotImplementedException ();
}
[MonoTODO]
public int IndexOf (TEntity entity)
{
throw new NotImplementedException ();
}
[MonoTODO]
int IList.IndexOf (object value)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void Insert (int index, TEntity entity)
{
throw new NotImplementedException ();
}
[MonoTODO]
void IList.Insert (int index, object value)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void Load ()
{
throw new NotImplementedException ();
}
[MonoTODO]
public bool Remove (TEntity entity)
{
throw new NotImplementedException ();
}
[MonoTODO]
void IList.Remove (object value)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void RemoveAt (int index)
{
throw new NotImplementedException ();
}
[MonoTODO]
public void SetSource (IEnumerable<TEntity> entitySource)
{
throw new NotImplementedException ();
}
[MonoTODO]
bool IListSource.ContainsListCollection {
get { throw new NotImplementedException (); }
}
[MonoTODO]
public int Count {
get { throw new NotImplementedException (); }
}
[MonoTODO]
public bool HasLoadedOrAssignedValues {
get { throw new NotImplementedException (); }
}
[MonoTODO]
public bool IsDeferred {
get { throw new NotImplementedException (); }
}
[MonoTODO]
bool IList.IsFixedSize {
get { throw new NotImplementedException (); }
}
[MonoTODO]
bool ICollection<TEntity>.IsReadOnly {
get { throw new NotImplementedException (); }
}
[MonoTODO]
bool IList.IsReadOnly {
get { throw new NotImplementedException (); }
}
[MonoTODO]
bool ICollection.IsSynchronized {
get { throw new NotImplementedException (); }
}
[MonoTODO]
public TEntity this [int index] {
get { throw new NotImplementedException (); }
set { throw new NotImplementedException (); }
}
[MonoTODO]
object IList.this [int index] {
get { throw new NotImplementedException (); }
set { throw new NotImplementedException (); }
}
[MonoTODO]
object ICollection.SyncRoot {
get { throw new NotImplementedException (); }
}
}
}

View File

@@ -1,111 +0,0 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Data.Linq.Mapping;
using System.Text;
#if MONO_STRICT
using System.Data.Linq;
using System.Data.Linq.Identity;
#else
using DbLinq.Data.Linq;
using DbLinq.Data.Linq.Identity;
#endif
using DbLinq.Linq;
using DbLinq.Util;
namespace DbLinq.Util
{
internal class CacheChecker
{
/// <summary>
/// Quote from MSDN:
/// If the object requested by the query is easily identifiable as one
/// already retrieved, no query is executed. The identity table acts as a cache
/// of all previously retrieved objects
/// From Matt Warren: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=345635&SiteID=1
/// The cache is checked when the query is a simple table.Where(pred) or table.First(pred) where the
/// predicate refers only to the primary key. Otherwise the query is always sent and the cache only checked
/// after the results are retrieved.
/// The DLINQ cache is not distributed or shared, it is local and contained within the context. It is only a
/// referential identity cache used to guarantee that two reads of the same entity return the same instance.
/// You are not expected to hold the cache for an extended duration (except possibly for a client scenario),
/// or share it across threads, processes, or machines in a cluster.
/// </summary>
public static bool TryRetrieveFromCache<S>(SessionVarsParsed vars, Expression scalarExpr, out S cachedRow)
{
cachedRow = default(S);
int count1 = vars.ExpressionChain.Count;
MethodCallExpression scalarMethodCall = scalarExpr.XMethodCall();
bool isSingleWhere = false;
LambdaExpression whereLambda = null;
if (count1 == 1 && scalarMethodCall.Arguments.Count == 1)
{
MethodCallExpression call0 = vars.ExpressionChain[0];
if (call0.Method.Name == "Where" && call0.Arguments.Count == 2)
{
//db.Customers.Where(id==1).Single()
isSingleWhere = true;
whereLambda = call0.Arguments[1].XLambda();
}
}
else if (count1 == 0 && scalarMethodCall.Arguments.Count == 2)
{
//db.Customers.Single(id==1)
isSingleWhere = true;
whereLambda = scalarMethodCall.Arguments[1].XLambda();
}
if ((!isSingleWhere) || whereLambda == null)
return false;
if (whereLambda.Parameters.Count != 1 || whereLambda.Parameters[0].NodeType != ExpressionType.Parameter)
return false;
if (whereLambda.Body.NodeType != ExpressionType.Equal)
return false;
BinaryExpression equals = (BinaryExpression)whereLambda.Body;
Expression left = equals.Left;
Expression right = equals.Right;
MemberExpression member;
ConstantExpression consta;
if (left.NodeType == ExpressionType.MemberAccess && right.NodeType == ExpressionType.Constant)
{
member = left.XMember();
consta = right.XConstant();
}
else if (left.NodeType == ExpressionType.Constant && right.NodeType == ExpressionType.Parameter)
{
member = right.XMember();
consta = left.XConstant();
}
else
{
return false;
}
if (member.Expression.NodeType != ExpressionType.Parameter)
return false;
//check that it's a primary key field
ColumnAttribute colAttrib = AttribHelper.GetColumnAttribute(member.Member);
if (colAttrib == null)
return false;
if (!colAttrib.IsPrimaryKey)
return false;
IdentityKey key = new IdentityKey(typeof(S), consta.Value);
DataContext context = vars.Context;
object cachedEntity = context.GetRegisteredEntityByKey(key);
if (cachedEntity == null)
return false;
cachedRow = (S)cachedEntity;
return true;
}
}
}

View File

@@ -1,270 +0,0 @@
#region MIT license
//
// MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
using DbLinq.Schema.Dbml;
namespace DbMetal.Generator.Implementation.CodeDomGenerator
{
#if !MONO_STRICT
public
#endif
abstract class AbstractCodeDomGenerator : ICodeGenerator
{
public abstract string LanguageCode { get; }
public abstract string Extension { get; }
public abstract void Write(TextWriter textWriter, Database dbSchema, GenerationContext context);
/// <summary>
/// Generates a C# source code wrapper for the database schema objects.
/// </summary>
/// <param name="database"></param>
/// <param name="filename"></param>
public void GenerateCSharp(Database database, string filename)
{
using (Stream stream = File.Open(filename, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(stream))
{
new CSharpCodeProvider().CreateGenerator(writer).GenerateCodeFromNamespace(GenerateCodeDomModel(database), writer, new CodeGeneratorOptions() { BracingStyle = "C" });
}
}
}
/// <summary>
/// Generates a Visual Basic source code wrapper for the database schema objects.
/// </summary>
/// <param name="database"></param>
/// <param name="filename"></param>
public void GenerateVisualBasic(Database database, string filename)
{
using (Stream stream = File.Open(filename, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(stream))
{
new VBCodeProvider().CreateGenerator(writer).GenerateCodeFromNamespace(GenerateCodeDomModel(database), writer, new CodeGeneratorOptions() { BracingStyle = "C" });
}
}
}
CodeThisReferenceExpression thisReference = new CodeThisReferenceExpression();
protected virtual CodeNamespace GenerateCodeDomModel(Database database)
{
CodeNamespace _namespace = new CodeNamespace(database.ContextNamespace);
_namespace.Imports.Add(new CodeNamespaceImport("System"));
_namespace.Imports.Add(new CodeNamespaceImport("System.ComponentModel"));
_namespace.Imports.Add(new CodeNamespaceImport("System.Data"));
_namespace.Imports.Add(new CodeNamespaceImport("System.Data.Linq.Mapping"));
_namespace.Imports.Add(new CodeNamespaceImport("System.Diagnostics"));
_namespace.Imports.Add(new CodeNamespaceImport("DbLinq.Linq"));
_namespace.Imports.Add(new CodeNamespaceImport("DbLinq.Linq.Mapping"));
_namespace.Comments.Add(new CodeCommentStatement(GenerateCommentBanner(database)));
_namespace.Types.Add(GenerateContextClass(database));
foreach (Table table in database.Tables)
_namespace.Types.Add(GenerateTableClass(table));
return _namespace;
}
protected virtual string GenerateCommentBanner(Database database)
{
var result = new StringBuilder();
// http://www.network-science.de/ascii/
// http://www.network-science.de/ascii/ascii.php?TEXT=MetalSequel&x=14&y=14&FONT=_all+fonts+with+your+text_&RICH=no&FORM=left&STRE=no&WIDT=80
result.Append(
@"
____ _ __ __ _ _
| _ \| |__ | \/ | ___| |_ __ _| |
| | | | '_ \| |\/| |/ _ \ __/ _` | |
| |_| | |_) | | | | __/ || (_| | |
|____/|_.__/|_| |_|\___|\__\__,_|_|
");
result.AppendLine(String.Format(" Auto-generated from {0} on {1}.", database.Name, DateTime.Now));
result.AppendLine(" Please visit http://linq.to/db for more information.");
return result.ToString();
}
protected virtual CodeTypeDeclaration GenerateContextClass(Database database)
{
var _class = new CodeTypeDeclaration() { IsClass = true, IsPartial = true, Name = database.Class, TypeAttributes = TypeAttributes.Public };
if (database.BaseType != null)
_class.BaseTypes.Add(database.BaseType);
else // TODO: something with less risk
_class.BaseTypes.Add(String.Format("DbLinq.{0}.{0}DataContext", database.Provider));
// CodeDom does not currently support partial methods. This will be a problem for VB. Will probably be fixed in .net 4
_class.Members.Add(new CodeSnippetTypeMember("\tpartial void OnCreated();"));
// Implement Constructor
var constructor = new CodeConstructor() { Attributes = MemberAttributes.Public, Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") } };
constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection"));
constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
_class.Members.Add(constructor);
// todo: override other constructors
foreach (Table table in database.Tables)
{
var tableType = new CodeTypeReference(table.Member);
var property = new CodeMemberProperty() { Type = new CodeTypeReference("Table", tableType), Name = table.Member, Attributes = MemberAttributes.Public | MemberAttributes.Final };
property.GetStatements.Add
(
new CodeMethodReturnStatement
(
new CodeMethodInvokeExpression
(
new CodeMethodReferenceExpression(thisReference, "GetTable", tableType)
)
)
);
_class.Members.Add(property);
}
return _class;
}
protected virtual CodeTypeDeclaration GenerateTableClass(Table table)
{
var _class = new CodeTypeDeclaration() { IsClass = true, IsPartial = true, Name = table.Member, TypeAttributes = TypeAttributes.Public };
_class.CustomAttributes.Add(new CodeAttributeDeclaration("Table", new CodeAttributeArgument("Name", new CodePrimitiveExpression(table.Name))));
// Implement Constructor
var constructor = new CodeConstructor() { Attributes = MemberAttributes.Public };
constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated")));
_class.Members.Add(constructor);
// todo: implement INotifyPropertyChanging
// Implement INotifyPropertyChanged
_class.BaseTypes.Add(typeof(INotifyPropertyChanged));
var propertyChangedEvent = new CodeMemberEvent() { Type = new CodeTypeReference(typeof(PropertyChangedEventHandler)), Name = "PropertyChanged", Attributes = MemberAttributes.Public };
_class.Members.Add(propertyChangedEvent);
var sendPropertyChangedMethod = new CodeMemberMethod() { Attributes = MemberAttributes.Family, Name = "SendPropertyChanged", Parameters = { new CodeParameterDeclarationExpression(typeof(System.String), "propertyName") } };
sendPropertyChangedMethod.Statements.Add
(
new CodeConditionStatement
(
new CodeSnippetExpression(propertyChangedEvent.Name + " != null"), // todo: covert this to CodeBinaryOperatorExpression
new CodeExpressionStatement
(
new CodeMethodInvokeExpression
(
new CodeMethodReferenceExpression(thisReference, propertyChangedEvent.Name),
thisReference,
new CodeObjectCreateExpression(typeof(PropertyChangedEventArgs), new CodeArgumentReferenceExpression("propertyName"))
)
)
)
);
_class.Members.Add(sendPropertyChangedMethod);
// CodeDom does not currently support partial methods. This will be a problem for VB. Will probably be fixed in .net 4
_class.Members.Add(new CodeSnippetTypeMember("\tpartial void OnCreated();"));
// todo: add these when the actually get called
//partial void OnLoaded();
//partial void OnValidate(System.Data.Linq.ChangeAction action);
// columns
foreach (Column column in table.Type.Columns)
{
var type = new CodeTypeReference(column.Type);
var columnMember = column.Member ?? column.Name;
var field = new CodeMemberField(type, "_" + columnMember);
_class.Members.Add(field);
var fieldReference = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name);
// CodeDom does not currently support partial methods. This will be a problem for VB. Will probably be fixed in .net 4
string onChangingPartialMethodName = String.Format("On{0}Changing", columnMember);
_class.Members.Add(new CodeSnippetTypeMember(String.Format("\tpartial void {0}({1} instance);", onChangingPartialMethodName, column.Type)));
string onChangedPartialMethodName = String.Format("On{0}Changed", columnMember);
_class.Members.Add(new CodeSnippetTypeMember(String.Format("\tpartial void {0}();", onChangedPartialMethodName)));
var property = new CodeMemberProperty();
property.Type = type;
property.Name = columnMember;
property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
property.CustomAttributes.Add
(
new CodeAttributeDeclaration
(
"Column",
new CodeAttributeArgument("Storage", new CodePrimitiveExpression(column.Storage)),
new CodeAttributeArgument("Name", new CodePrimitiveExpression(column.Name)),
new CodeAttributeArgument("DbType", new CodePrimitiveExpression(column.DbType)),
new CodeAttributeArgument("CanBeNull", new CodePrimitiveExpression(column.CanBeNull)),
new CodeAttributeArgument("IsPrimaryKey", new CodePrimitiveExpression(column.IsPrimaryKey))
)
);
property.CustomAttributes.Add(new CodeAttributeDeclaration("DebuggerNonUserCode"));
property.GetStatements.Add(new CodeMethodReturnStatement(fieldReference));
property.SetStatements.Add
(
new CodeConditionStatement
(
new CodeSnippetExpression(field.Name + " != value"), // todo: covert this to CodeBinaryOperatorExpression
new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChangingPartialMethodName, new CodePropertySetValueReferenceExpression())),
new CodeAssignStatement(fieldReference, new CodePropertySetValueReferenceExpression()),
new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, sendPropertyChangedMethod.Name, new CodePrimitiveExpression(property.Name))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChangedPartialMethodName))
)
);
_class.Members.Add(property);
}
// TODO: implement associations
// TODO: implement functions / procedures
// TODO: Override Equals and GetHashCode
return _class;
}
}
}

View File

@@ -1,49 +0,0 @@
#region MIT license
//
// MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System.CodeDom.Compiler;
using System.IO;
using DbLinq.Schema.Dbml;
using Microsoft.CSharp;
namespace DbMetal.Generator.Implementation.CodeDomGenerator
{
#if !MONO_STRICT
public
#endif
class CSharpCodeDomGenerator: AbstractCodeDomGenerator
{
public override string LanguageCode { get { return "C#2"; } }
public override string Extension { get { return ".cs2"; } }
public override void Write(TextWriter textWriter, Database dbSchema, GenerationContext context)
{
new CSharpCodeProvider().CreateGenerator(textWriter).GenerateCodeFromNamespace(GenerateCodeDomModel(dbSchema), textWriter,
new CodeGeneratorOptions() { BracingStyle = "C" });
}
}
}

View File

@@ -1,49 +0,0 @@
#region MIT license
//
// MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System.CodeDom.Compiler;
using System.IO;
using DbLinq.Schema.Dbml;
using Microsoft.VisualBasic;
namespace DbMetal.Generator.Implementation.CodeDomGenerator
{
#if !MONO_STRICT
public
#endif
class VisualBasicCodeDomGenerator : AbstractCodeDomGenerator
{
public override string LanguageCode { get { return "VB"; } }
public override string Extension { get { return ".vb"; } }
public override void Write(TextWriter textWriter, Database dbSchema, GenerationContext context)
{
new VBCodeProvider().CreateGenerator(textWriter).GenerateCodeFromNamespace(GenerateCodeDomModel(dbSchema), textWriter,
new CodeGeneratorOptions() { BracingStyle = "C" });
}
}
}

View File

@@ -1,131 +0,0 @@
#region MIT license
//
// MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DbLinq.Schema;
using DbLinq.Util;
namespace DbMetal.Schema
{
/// <summary>
/// this class contains functionality common to all vendors -
/// a) rename field Alltypes.Alltypes to Alltypes.Contents
/// b) rename field Employees.Employees to Employees.RefersToEmployees
/// c) rename field Alltypes.int to Alltypes.int_
/// </summary>
public class SchemaPostprocess
{
public static void PostProcess_DB(DbLinq.Schema.Dbml.Database schema)
{
if (schema == null)
return;
//sort tables, parent tables first
// picrap: how useful was this?
//TableSorter sorter = new TableSorter(schema.Tables);
//schema.Tables.Sort(sorter);
foreach (var tbl in schema.Tables)
{
PostProcess_Table(tbl);
}
}
public static void PostProcess_Table(DbLinq.Schema.Dbml.Table table)
{
// picrap: this is processed earlier
//table.Member = Util.FormatTableName(table.Type.Name, util.PluralEnum.Pluralize);
//table.Type.Name = Util.FormatTableName(table.Type.Name, util.PluralEnum.Singularize);
//if (mmConfig.renamesFile != null)
//{
// table.Member = Util.Rename(table.Member);
//}
foreach (DbLinq.Schema.Dbml.Column col in table.Type.Columns)
{
if (col.Member == table.Type.Name)
col.Member = "Contents"; //rename field Alltypes.Alltypes to Alltypes.Contents
// picrap processed earlier
//col.Storage = "_" + col.Name;
// picrap moved to CSCodeWriter
//if (CSharp.IsCsharpKeyword(col.Storage))
// col.Storage += "_"; //rename column 'int' -> 'int_'
//if (CSharp.IsCsharpKeyword(col.Member))
// col.Member += "_"; //rename column 'int' -> 'int_'
}
Dictionary<string, bool> knownAssocs = new Dictionary<string, bool>();
foreach (DbLinq.Schema.Dbml.Association assoc in table.Type.Associations)
{
// picrap: processed earlier
//assoc.Type = Util.FormatTableName(assoc.Type, util.PluralEnum.Singularize);
//util.PluralEnum pluralEnum = assoc.IsForeignKey
// ? util.PluralEnum.Singularize
// : util.PluralEnum.Pluralize;
//referring to parent: "public Employee Employee"
//referring to child: "public EntityMSet<Product> Products"
//assoc.Member = Util.FormatTableName(assoc.Member, pluralEnum);
if (assoc.Member == table.Type.Name)
{
string thisKey = assoc.ThisKey ?? "_TODO_L35";
//self-join: rename field Employees.Employees to Employees.RefersToEmployees
assoc.Member = thisKey + assoc.Member;
}
if (knownAssocs.ContainsKey(assoc.Member))
{
//this is the Andrus test case in Pgsql:
// create table t1 ( private int primary key);
// create table t2 ( f1 int references t1, f2 int references t1 );
assoc.Member += "_" + assoc.Name;
}
// picrap: handled previously
//if (mmConfig.renamesFile != null)
//{
// assoc.Member = Util.Rename(assoc.Member);
//}
//if (assoc.Member == "employeeterritories" || assoc.Member == "Employeeterritories")
// assoc.Member = "EmployeeTerritories"; //hack to help with Northwind
knownAssocs[assoc.Member] = true;
}
}
}
}

View File

@@ -1,126 +0,0 @@
#region MIT license
////////////////////////////////////////////////////////////////////
// MIT license:
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
//
// Authors:
// Jiri George Moudry
// Andrey Shchekin
////////////////////////////////////////////////////////////////////
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DbLinq.Schema;
namespace DbMetal.Util
{
/// <summary>
/// sort tables - parent tables first, child tables next.
/// </summary>
public class TableSorter : IComparer<DbLinq.Schema.Dbml.Table>
{
Dictionary<string, DbLinq.Schema.Dbml.Table> _typeNameToTableMap; // = tables.ToDictionary(t => t.Name);
//Dictionary<DbLinq.Schema.Dbml.Table, int> _originalOrder = new Dictionary<DbLinq.Schema.Dbml.Table, int>();
public TableSorter(IEnumerable<DbLinq.Schema.Dbml.Table> tables)
{
_typeNameToTableMap = tables.ToDictionary(t => t.Type.Name);
//int indx = 0;
foreach (DbLinq.Schema.Dbml.Table t in tables)
{
//_originalOrder[t] = indx++;
foreach (DbLinq.Schema.Dbml.Table child in EnumChildTables(t))
{
child._isChild = true;
}
}
}
#region IComparer<Table> Members
public int Compare(DbLinq.Schema.Dbml.Table x, DbLinq.Schema.Dbml.Table y)
{
if (x == y)
return 0; //crappy sort implementation in .NET framework?!
foreach (DbLinq.Schema.Dbml.Table child_of_x in EnumChildTables(x))
{
if (y == child_of_x)
return -1;
}
foreach (DbLinq.Schema.Dbml.Table child_of_y in EnumChildTables(y))
{
if (x == child_of_y)
return +1;
}
//if we get here, x/y are not above or below each other.
return x._isChild.CompareTo(y._isChild);
//return 0;
}
#endregion
#region recursive walk through child table hierarchy
private IEnumerable<DbLinq.Schema.Dbml.Table> EnumChildTables(DbLinq.Schema.Dbml.Table parent)
{
Dictionary<DbLinq.Schema.Dbml.Table, bool> visitedMap = new Dictionary<DbLinq.Schema.Dbml.Table, bool>();
return EnumChildTables_(parent, visitedMap);
}
/// <summary>
/// recursively list all child tables.
/// We use visitedMap to prevent duplicates.
/// </summary>
private IEnumerable<DbLinq.Schema.Dbml.Table> EnumChildTables_(DbLinq.Schema.Dbml.Table parent, Dictionary<DbLinq.Schema.Dbml.Table, bool> visitedMap)
{
//In Northwind DB, Employee.ReportsTo points back to itself,
//mark as visited to prevent recursion
visitedMap[parent] = true;
var q1 = parent.Type.Associations.Where(a => !a.IsForeignKey
&& a.OtherKey != null
&& _typeNameToTableMap.ContainsKey(a.Type));
var q = q1.ToList(); //for debugging
//loop through direct child tables ...
foreach (var assoc in q)
{
DbLinq.Schema.Dbml.Table child = _typeNameToTableMap[assoc.Type];
if (visitedMap.ContainsKey(child))
continue;
visitedMap[child] = true;
yield return child;
//... and recurse into children of children:
foreach (DbLinq.Schema.Dbml.Table child2 in EnumChildTables_(child, visitedMap))
{
yield return child2;
}
}
}
#endregion
}
}