상속: IVisitable
		/// <summary>
		/// Dispatches the call to the extensions.
		/// </summary>
		/// <param name="fi">The field info reflection object.</param>
		/// <param name="model">The model.</param>
		public void ProcessField(FieldInfo fi, ActiveRecordModel model)
		{
			foreach(IModelBuilderExtension extension in extensions)
			{
				extension.ProcessField(fi, model);
			}
		}
		/// <summary>
		/// Dispatches the call to the extensions.
		/// </summary>
		/// <param name="pi">The property info reflection object.</param>
		/// <param name="belongsToModel">The belongs to model.</param>
		/// <param name="model">The model.</param>
		public void ProcessBelongsTo(PropertyInfo pi, BelongsToModel belongsToModel, ActiveRecordModel model)
		{
			foreach(IModelBuilderExtension extension in extensions)
			{
				extension.ProcessBelongsTo(pi, belongsToModel, model);
			}
		}
예제 #3
0
		private IList ObtainListableProperties(ActiveRecordModel model)
		{
			var properties = new ArrayList();
	
			ObtainPKProperty();

			if (model.Parent != null)
			{
				properties.AddRange( ObtainListableProperties(model.Parent) );
			}
	
			foreach(var propModel in model.Properties)
			{
				if (IsNotSupported(propModel.Property.PropertyType)) continue;

				properties.Add(propModel.Property);
			}
	
			foreach(var prop in model.NotMappedProperties)
			{
				if (IsNotSupported(prop.PropertyType)) continue;

				properties.Add(prop);
			}

			return properties;
		}
		/// <summary>
		/// Dispatches the call to the extensions.
		/// </summary>
		/// <param name="type">The type.</param>
		/// <param name="model">The model.</param>
		public void ProcessClass(Type type, ActiveRecordModel model)
		{
			foreach(IModelBuilderExtension extension in extensions)
			{
				extension.ProcessClass(type, model);
			}
		}
		public String LinkToEdit(ActiveRecordModel model, bool useModelName, 
		                         String text, object key, IDictionary attributes)
		{
			string targetAction = "edit" + (useModelName ? model.Type.Name : "");

			return LinkTo(targetAction, key, text, attributes);
		}
예제 #6
0
        private void ProcessFields(Type type, ActiveRecordModel model)
        {
            //Check persistent fields of the base class as well
            if (ShouldCheckBase(type))
            {
                ProcessFields(type.BaseType, model);
            }

            FieldInfo[] fields = type.GetFields(FieldDefaultBindingFlags);

            foreach (FieldInfo field in fields)
            {
                foreach (object attribute in field.GetCustomAttributes(false))
                {
                    if (attribute is FieldAttribute)
                    {
                        FieldAttribute fieldAtt = (FieldAttribute)attribute;

                        model.Fields.Add(new FieldModel(field, fieldAtt));
                    }
                    else if (attribute is CompositeUserTypeAttribute)
                    {
                        CompositeUserTypeAttribute fieldAtt = attribute as CompositeUserTypeAttribute;
                        fieldAtt.Access = PropertyAccess.Field;

                        model.CompositeUserType.Add(new CompositeUserTypeModel(field, field.FieldType, fieldAtt));
                    }
                }

                if (extension != null)
                {
                    extension.ProcessField(field, model);
                }
            }
        }
예제 #7
0
 private void EnsureOnlyOneKey(ActiveRecordModel model)
 {
     if (model.Ids.Count > 1)
     {
         throw new ActiveRecordException("Composite keys are not supported yet. Type " + model.Type.FullName);
     }
 }
예제 #8
0
        public void CreateXml(ActiveRecordModel model)
        {
            CreateXmlPI();
            StartMappingNode();
            Ident();
            VisitModel(model);
            Dedent();
            EndMappingNode();

#if OUTPUTXML
            String file = model.Type.Name + ".maping.xml";

            System.IO.File.Delete(file);

            using (System.IO.FileStream fs = System.IO.File.OpenWrite(file))
            {
                String xml = Xml;

                byte[] ba = System.Text.ASCIIEncoding.UTF8.GetBytes(xml);

                fs.Write(ba, 0, ba.Length);

                fs.Flush();
            }
#endif
        }
        private static void AssertHasValidKey(ActiveRecordModel model)
        {
            // Nested types do not have primary keys
            if (model.IsNestedType)
            {
                return;
            }

            // Need to make the check this way because of inheritance,
            // where the current class doesn't have
            // a primary key but the base class does
            ActiveRecordModel tmpModel = model;

            while (tmpModel != null && tmpModel.PrimaryKey == null && tmpModel.CompositeKey == null)
            {
                tmpModel = tmpModel.Parent;
            }

            if (tmpModel != null && tmpModel.PrimaryKey != null && tmpModel.CompositeKey != null)
            {
                throw new ActiveRecordException(
                          String.Format(
                              "A type cannot have a primary key and a composite key at the same time. Check type {0}",
                              model.Type.FullName));
            }

            if (tmpModel == null || tmpModel.PrimaryKey == null && tmpModel.CompositeKey == null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "A type must declare a primary key. Check type {0}", model.Type.FullName));
            }
        }
예제 #10
0
        public virtual void VisitModel(ActiveRecordModel model)
        {
            if (!visited.Contains(model))
            {
                visited.Add(model, String.Empty);
            }
            else
            {
                return;
            }

            VisitNodes(model.Ids);
            VisitNode(model.Key);
            VisitNode(model.Version);
            VisitNode(model.Timestamp);
            VisitNodes(model.JoinedClasses);
            VisitNodes(model.Classes);
            VisitNodes(model.Fields);
            VisitNodes(model.Anys);
            VisitNodes(model.Properties);
            VisitNodes(model.OneToOnes);
            VisitNodes(model.BelongsTo);
            VisitNodes(model.HasMany);
            VisitNodes(model.HasAndBelongsToMany);
            VisitNodes(model.HasManyToAny);
            VisitNodes(model.CollectionIDs);
            VisitNodes(model.Hilos);
            VisitNodes(model.Components);
        }
예제 #11
0
		/// <summary>
		/// Visits the model.
		/// </summary>
		/// <param name="model">The model.</param>
		public virtual void VisitModel(ActiveRecordModel model)
		{
			if (!visited.ContainsKey(model))
			{
				visited.Add(model, String.Empty);
			}
			else
			{
				return;
			}

			VisitNode(model.PrimaryKey);
			VisitNode(model.CompositeKey);
			VisitNode(model.Key);
			VisitNode(model.Version);
			VisitNode(model.Timestamp);
			VisitNodes(model.JoinedClasses);
			VisitNodes(model.JoinedTables);
			VisitNodes(model.BelongsTo);
			VisitNodes(model.Classes);
			VisitNodes(model.Fields);
			VisitNodes(model.Anys);
			VisitNodes(model.Properties);
			VisitNodes(model.OneToOnes);
			VisitNodes(model.HasMany);
			VisitNodes(model.HasAndBelongsToMany);
			VisitNodes(model.HasManyToAny);
			VisitNodes(model.CollectionIDs);
			VisitNodes(model.Hilos);
			VisitNodes(model.Components);
			VisitNodes(model.CompositeUserType);
		}
예제 #12
0
		/// <summary>
		/// Creates the XML.
		/// </summary>
		/// <param name="model">The model.</param>
		public void CreateXml(ActiveRecordModel model)
		{
			CreateXmlPI();
			StartMappingNode(model.UseAutoImport);
			Ident();
			VisitModel(model);
			Dedent();
			EndMappingNode();

			if (ActiveRecordModel.isDebug)
			{
				String file = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, model.Type.Name + ".hbm.xml");

				System.IO.File.Delete(file);

				using(System.IO.FileStream fs = System.IO.File.OpenWrite(file))
				{
					String xml = Xml;

					byte[] ba = System.Text.ASCIIEncoding.Unicode.GetBytes(xml);

					fs.Write(ba, 0, ba.Length);

					fs.Flush();
				}
			}
		}
 /// <summary>
 /// Dispatches the call to the extensions.
 /// </summary>
 /// <param name="type">The type.</param>
 /// <param name="model">The model.</param>
 public void ProcessClass(Type type, ActiveRecordModel model)
 {
     foreach (IModelBuilderExtension extension in extensions)
     {
         extension.ProcessClass(type, model);
     }
 }
		/// <summary>
		/// Dispatches the call to the extensions.
		/// </summary>
		/// <param name="pi">The property info reflection object.</param>
		/// <param name="model">The model.</param>
		public void ProcessProperty(PropertyInfo pi, ActiveRecordModel model)
		{
			foreach(IModelBuilderExtension extension in extensions)
			{
				extension.ProcessProperty(pi, model);
			}
		}
        public EditCatalogWindow (string model, object record,
            ActiveRecordModel mod, EventHandler OnSaveButtonClicked, Gtk.Window parent) :
                base(Gtk.WindowType.Toplevel)
        {
            this.Build ();
            this.TransientFor = parent;
            this.Modal = true;
            this.model = model;
            this.mod = mod;
            this.record = (ActiveRecordBase)record;
            this.OnRecordSaved = OnSaveButtonClicked;
            this.WindowPosition = Gtk.WindowPosition.CenterAlways;
            this.Title = model + " creation";

            modelLabel.Text = model;

            if (!mod.PropertyDictionary.Keys.Contains("Notes"))
            {
                editRecord.HideNotesEntry ();

            }

            PropertyInfo p = record.GetType().GetProperty("ParentId");
            if (p != null) {
               MethodInfo modelMethod = record.GetType().GetMethod("ParentModel");
               editRecord.ParentName = modelMethod.Invoke (record, null) as String;

               MethodInfo nameMethod = record.GetType().GetMethod("ParentName");
               editRecord.ParentValue = nameMethod.Invoke (record, null) as String;

           } else {
               editRecord.HideParentEntry ();
           }
        }
 /// <summary>
 /// Dispatches the call to the extensions.
 /// </summary>
 /// <param name="pi">The property info reflection object.</param>
 /// <param name="hasAndBelongManyModel">The has and belong many model.</param>
 /// <param name="model">The model.</param>
 public void ProcessHasAndBelongsToMany(PropertyInfo pi, HasAndBelongsToManyModel hasAndBelongManyModel,
                                        ActiveRecordModel model)
 {
     foreach (IModelBuilderExtension extension in extensions)
     {
         extension.ProcessHasAndBelongsToMany(pi, hasAndBelongManyModel, model);
     }
 }
예제 #17
0
        /// <summary>
        /// Gets an array containing the <see cref="Framework.Internal.ActiveRecordModel"/> for every registered ActiveRecord class.
        /// </summary>
        public static ActiveRecordModel[] GetModels()
        {
            ActiveRecordModel[] modelArray = new ActiveRecordModel[type2Model.Values.Count];

            type2Model.Values.CopyTo(modelArray, 0);

            return(modelArray);
        }
예제 #18
0
 private void WriteDiscriminator(ActiveRecordModel model)
 {
     if (model.IsDiscriminatorBase)
     {
         AppendF("<discriminator {0} {1} />",
                 MakeAtt("column", model.ActiveRecordAtt.DiscriminatorColumn),
                 WriteIfNonNull("type", model.ActiveRecordAtt.DiscriminatorType));
     }
 }
예제 #19
0
        private static void ProcessJoinedTables(Type type, ActiveRecordModel model)
        {
            object[] attrs = type.GetCustomAttributes(typeof(JoinedTableAttribute), false);

            foreach (JoinedTableAttribute att in attrs)
            {
                JoinedTableModel jtm = new JoinedTableModel(att);
                model.JoinedTables.Add(jtm);
            }
        }
        /// <summary>
        /// Visits the nested.
        /// </summary>
        /// <param name="model">The model.</param>
        public override void VisitNested(NestedModel model)
        {
            Type type = model.Property.DeclaringType;

            ActiveRecordModel parent = arCollection[type];

            model.Model.Parent = parent;

            base.VisitNested(model);
        }
        /// <summary>
        /// Visits the model.
        /// </summary>
        /// <param name="model">The model.</param>
        public override void VisitModel(ActiveRecordModel model)
        {
            ActiveRecordModel savedModel = currentModel;

            try
            {
                currentModel = model;

                if (model.IsDiscriminatorBase || model.IsJoinedSubClassBase ||
                    model.IsDiscriminatorSubClass || model.IsJoinedSubClass)
                {
                    foreach (ActiveRecordModel child in arCollection)
                    {
                        if (IsChildClass(model, child))
                        {
                            child.IsDiscriminatorSubClass = model.ActiveRecordAtt.DiscriminatorValue != null;
                            child.IsJoinedSubClass        = child.Key != null;
                            child.Parent = model;

                            if (child.IsDiscriminatorSubClass)
                            {
                                // Needed for deep hierarchies
                                if (model.Classes.Contains(child) == false)
                                {
                                    // Discriminator subclass
                                    model.Classes.Add(child);
                                }
                            }
                            else if (child.IsJoinedSubClass)
                            {
                                // Needed for deep hierarchies
                                if (model.JoinedClasses.Contains(child) == false)
                                {
                                    // Joined subclass
                                    model.JoinedClasses.Add(child);
                                }
                            }
                        }
                    }
                }

                VisitNodes(model.JoinedClasses);
                VisitNodes(model.Classes);

                base.VisitModel(model);

                // They should have been connected by now
                model.CollectionIDs.Clear();
                model.Hilos.Clear();
            }
            finally
            {
                currentModel = savedModel;
            }
        }
		/// <summary>
		/// Visits the model.
		/// </summary>
		/// <param name="model">The model.</param>
		public override void VisitModel(ActiveRecordModel model)
		{
			ActiveRecordModel savedModel = currentModel;

			try
			{
				currentModel = model;

				if (model.IsDiscriminatorBase || model.IsJoinedSubClassBase ||
					model.IsDiscriminatorSubClass || model.IsJoinedSubClass)
				{
					foreach(ActiveRecordModel child in arCollection)
					{
						if (IsChildClass(model, child))
						{
							child.IsDiscriminatorSubClass = model.ActiveRecordAtt.DiscriminatorValue != null;
							child.IsJoinedSubClass = child.Key != null;
							child.Parent = model;

							if (child.IsDiscriminatorSubClass)
							{
								// Needed for deep hierarchies
								if (model.Classes.Contains(child) == false)
								{
									// Discriminator subclass
									model.Classes.Add(child);
								}
							} 
							else if (child.IsJoinedSubClass)
							{
								// Needed for deep hierarchies
								if (model.JoinedClasses.Contains(child) == false)
								{
									// Joined subclass
									model.JoinedClasses.Add(child);
								}
							}
						}
					}
				}

				VisitNodes(model.JoinedClasses);
				VisitNodes(model.Classes);

				base.VisitModel(model);

				// They should have been connected by now
				model.CollectionIDs.Clear();
				model.Hilos.Clear();
			}
			finally
			{
				currentModel = savedModel;
			}
		}
		/// <summary>
		/// Populates the model from tye type
		/// </summary>
		/// <param name="model">The model.</param>
		/// <param name="type">The type.</param>
		private static void PopulateModel(ActiveRecordModel model, Type type)
		{
			ProcessActiveRecordAttribute(type, model);

			ProcessImports(type, model);

			ProcessJoinedBaseAttribute(type, model);

			ProcessProperties(type, model);

			ProcessFields(type, model);
		}
예제 #24
0
		private object LoadActiveRecord(Type type, object pk, ARFetchAttribute attr, ActiveRecordModel model)
		{
			object instance = null;

			if (pk != null && !String.Empty.Equals(pk))
			{
				PrimaryKeyModel pkModel = ObtainPrimaryKey(model);

				Type pkType = pkModel.Property.PropertyType;

				bool conversionSucceeded;
				object convertedPk = converter.Convert(pkType, pk.GetType(), pk, out conversionSucceeded);
				
				if (!conversionSucceeded)
				{
					throw new RailsException("ARFetcher could not convert PK {0} to type {1}", pk, pkType);
				}

				if (attr.Eager == null || attr.Eager.Length == 0)
				{
					// simple load
					instance = ActiveRecordMediator.FindByPrimaryKey(type, convertedPk, attr.Required);
				}
				else
				{
					// load using eager fetching of lazy collections
					DetachedCriteria criteria = DetachedCriteria.For(type);
					criteria.Add(Expression.Eq(pkModel.Property.Name, convertedPk));
					foreach (string associationToEagerFetch in attr.Eager.Split(','))
					{
						string clean = associationToEagerFetch.Trim();
						if (clean.Length == 0)
						{
							continue;
						}
						
						criteria.SetFetchMode(clean, FetchMode.Eager);
					}
					
					object[] result = (object[]) ActiveRecordMediator.FindAll(type, criteria);
					if (result.Length > 0)
						instance = result[0];
				}
			}

			if (instance == null && attr.Create)
			{
				instance = Activator.CreateInstance(type);
			}

			return instance;
		}
예제 #25
0
		public String LinkToNew(ActiveRecordModel model, bool useModelName, String text, IDictionary attributes)
		{
			if (useModelName)
			{
				return String.Format("<a href=\"new{0}.{1}\" {3}>{2}</a>", model.Type.Name, 
					Controller.Context.UrlInfo.Extension, text, GetAttributes(attributes));
			}
			else
			{
				return String.Format("<a href=\"new.{0}\" {2}>{1}</a>", 
					Controller.Context.UrlInfo.Extension, text, GetAttributes(attributes));
			}
		}
예제 #26
0
        private static void ProcessActiveRecordAttribute(Type type, ActiveRecordModel model)
        {
            object[] attrs = type.GetCustomAttributes(typeof(ActiveRecordAttribute), false);

            if (attrs.Length == 0)
            {
                throw new ActiveRecordException(
                          String.Format("Type {0} is not using the ActiveRecordAttribute, which is obligatory.", type.FullName));
            }

            ActiveRecordAttribute arAttribute = attrs[0] as ActiveRecordAttribute;

            PopulateActiveRecordAttribute(arAttribute, model);
        }
예제 #27
0
		public String LinkToEdit(ActiveRecordModel model, bool useModelName, 
		                         String text, object key, IDictionary attributes)
		{
			if (useModelName)
			{
				return String.Format("<a href=\"edit{0}.{1}?id={4}\" {3}>{2}</a>", model.Type.Name, 
					Controller.Context.UrlInfo.Extension, text, GetAttributes(attributes), key);
			}
			else
			{
				return String.Format("<a href=\"edit.{0}?id={3}\" {2}>{1}</a>", 
					Controller.Context.UrlInfo.Extension, text, GetAttributes(attributes), key);
			}
		}
        public override void VisitModel(ActiveRecordModel model)
        {
            currentModel = model;

            if (model.IsDiscriminatorBase && model.IsJoinedSubClassBase)
            {
                throw new ActiveRecordException(String.Format(
                                                    "Unfortunatelly you can't have a discriminator class " +
                                                    "and a joined subclass at the same time - check type {0}", model.Type.FullName));
            }

            if (model.Version != null && model.Timestamp != null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "You can't specify a version and a timestamp properties, only one of them " +
                                                    "- check type {0}", model.Type.FullName));
            }

            if (model.IsDiscriminatorSubClass || model.IsJoinedSubClass)
            {
                if (model.Version != null || model.Timestamp != null)
                {
                    throw new ActiveRecordException(String.Format(
                                                        "A joined subclass or discriminator subclass can't specify a version or timestamp " +
                                                        "- check type {0}", model.Type.FullName));
                }
            }

            if (model.IsJoinedSubClass && model.Key == null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "A joined subclass must specify a key property. Use the JoinedKeyAttribute to denote the shared key. " +
                                                    "- check type {0}", model.Type.FullName));
            }

            if (model.IsNestedType)
            {
                if (model.Version != null || model.Timestamp != null)
                {
                    throw new ActiveRecordException(String.Format(
                                                        "A nested type is not allowed to have version or timestamped fields " +
                                                        "- check type {0}", model.Type.FullName));
                }
            }

            ThrowIfDoesntHavePrimaryKey(model);

            base.VisitModel(model);
        }
예제 #29
0
        public override String ToString()
        {
            Framework.Internal.ActiveRecordModel model = GetModel(GetType());

            if (model == null || model.Ids.Count != 1)
            {
                return(base.ToString());
            }

            Framework.Internal.PrimaryKeyModel pkModel = (Framework.Internal.PrimaryKeyModel)model.Ids[0];

            object pkVal = pkModel.Property.GetValue(this, null);

            return(base.ToString() + "#" + pkVal);
        }
		/// <summary>
		/// Creates a <see cref="ActiveRecordModel"/> from the specified type.
		/// </summary>
		/// <param name="type">The type.</param>
		/// <returns></returns>
		public ActiveRecordModel Create(Type type)
		{
			if (type == null) throw new ArgumentNullException("type");

			if (type.IsDefined(typeof(ActiveRecordSkipAttribute), false)) return null;

			ActiveRecordModel model = new ActiveRecordModel(type);

			coll.Add(model);

			PopulateModel(model, type);

			ActiveRecordBase.Register(type, model);

			return model;
		}
예제 #31
0
		public static PrimaryKeyModel ObtainPKProperty(ActiveRecordModel model)
		{
			if (model == null) return null;

			ActiveRecordModel curModel = model;

			while (curModel != null)
			{
				if (curModel.PrimaryKey != null)
				{
					return curModel.PrimaryKey;
				}

				curModel = curModel.Parent;
			}

			return null;
		}	
예제 #32
0
        public RecordNode (Object record, ActiveRecordModel mod)
        {
            Record = record;
            this.mod = mod;
            PropertyInfo nameProp =  mod.PropertyDictionary["Name"].Property;
            Name = nameProp.GetValue(record, null) as String;
            MethodInfo parentMethod = mod.Type.GetMethod("ParentName");
            hasParent = parentMethod != null;
            if (hasParent) {
                PropertyInfo parentProp =  mod.Type.GetProperty ("ParentId");
                parentId = (parentProp.GetValue(record, null) as int?).Value;
                if (parentId > 0)
                    ParentName = parentMethod.Invoke (record, null) as String;
                else
                    ParentName = "";
            } else {
                ParentName = "";
            }

            MethodInfo categoryMethod = mod.Type.GetMethod("CategoryName");
            hasCategory = categoryMethod != null;
            if (hasCategory) {
                PropertyInfo categoryProp =  mod.Type.GetProperty ("CategoryId");
                categoryId = (categoryProp.GetValue(record, null) as int?).Value;
                if (categoryId > 0)
                    CategoryName = categoryMethod.Invoke (record, null) as String;
                else
                    CategoryName = "";
            } else {
                CategoryName = "";
            }

            hasNotes = mod.PropertyDictionary.ContainsKey ("Notes");
            if (hasNotes) {
                PropertyInfo notesProp =  mod.Type.GetProperty ("Notes");
                Notes = (notesProp.GetValue(record, null) as String);
            } else {
                Notes = "";
            }
			

            Selected = false;
        }
예제 #33
0
        /// <summary>
        /// Populates the model from tye type
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="type">The type.</param>
        private void PopulateModel(ActiveRecordModel model, Type type)
        {
            if (extension != null)
            {
                extension.ProcessClass(type, model);
            }

            ProcessActiveRecordAttribute(type, model);

            ProcessImports(type, model);

            ProcessJoinedBaseAttribute(type, model);

            ProcessJoinedTables(type, model);

            ProcessProperties(type, model);

            ProcessFields(type, model);
        }
        /// <summary>
        /// Visits the property.
        /// </summary>
        /// <remarks>
        /// Infer column name and whatever this propery can be null or not
        /// Also catch common mistake of try to use [Property] on an entity, instead of [BelongsTo]
        /// Ensure that joined properties have a joined table.
        /// </remarks>
        /// <param name="model">The model.</param>
        public override void VisitProperty(PropertyModel model)
        {
            if (model.PropertyAtt.Column == null)
            {
                model.PropertyAtt.Column = model.Property.Name;
            }

            // Append column prefix
            model.PropertyAtt.Column = columnPrefix + model.PropertyAtt.Column;

            Type propertyType = model.Property.PropertyType;

            if (NHibernateNullablesSupport.IsNHibernateNullableType(propertyType) &&
                (model.PropertyAtt.ColumnType == null || model.PropertyAtt.ColumnType.Length == 0))
            {
                model.PropertyAtt.NotNull    = false;
                model.PropertyAtt.ColumnType = NHibernateNullablesSupport.GetITypeTypeNameForNHibernateNullable(propertyType);
            }

            if (propertyType.IsGenericType &&
                propertyType.GetGenericTypeDefinition() == typeof(Nullable <>) &&
                String.IsNullOrEmpty(model.PropertyAtt.ColumnType))
            {
                model.PropertyAtt.NotNull    = false;
                model.PropertyAtt.ColumnType = ObtainNullableTypeNameForCLRNullable(propertyType);
            }

            if (ActiveRecordModel.GetModel(propertyType) != null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "You can't use [Property] on {0}.{1} because {2} is an active record class, did you mean to use BelongTo?",
                                                    model.Property.DeclaringType.Name, model.Property.Name, propertyType.FullName));
            }

            JoinedTableModel joinedTable = ObtainJoinedTableIfPresent(model.Property, model.PropertyAtt);

            if (joinedTable != null)
            {
                joinedTable.Properties.Add(model);
            }
        }
예제 #35
0
        private static void ProcessImports(Type type, ActiveRecordModel model)
        {
            object[] attrs = type.GetCustomAttributes(typeof(ImportAttribute), false);

            if (attrs == null || attrs.Length == 0)
            {
                return;
            }

            if (HasJoinedBase(type))
            {
                string message = string.Format("Type {0} declares Imports but it has a joined base class. " +
                                               "All imports must be declared on a base class.", type);
                throw new ActiveRecordException(message);
            }

            foreach (ImportAttribute att in attrs)
            {
                model.Imports.Add(new ImportModel(att));
            }
        }
        private static void ThrowIfDoesntHavePrimaryKey(ActiveRecordModel model)
        {
            if (model.IsNestedType)            //nested types do not have primary keys
            {
                return;
            }
            //Need to make the check this way because of inheritance, where the current class doesn't have
            //a primary key but the base class does
            ActiveRecordModel tmpModel = model;

            while (tmpModel != null && tmpModel.Ids.Count == 0)
            {
                tmpModel = tmpModel.Parent;
            }
            if (tmpModel == null || tmpModel.Ids.Count == 0)
            {
                throw new ActiveRecordException(String.Format(
                                                    "A type must declare a primary key. " +
                                                    "Check type {0}", model.Type.FullName));
            }
        }
예제 #37
0
        /// <summary>
        /// Creates a <see cref="ActiveRecordModel"/> from the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public ActiveRecordModel Create(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (type.IsDefined(typeof(ActiveRecordSkipAttribute), false))
            {
                return(null);
            }

            ActiveRecordModel model = new ActiveRecordModel(type);

            coll.Add(model);

            PopulateModel(model, type);

            ActiveRecordBase.Register(type, model);

            return(model);
        }
예제 #38
0
		public ICollection GetModelHierarchy(ActiveRecordModel model, object instance)
		{
			ArrayList list = new ArrayList();

			ActiveRecordModel hierarchy = model;

			while(hierarchy != null)
			{
				list.Add(hierarchy);

				hierarchy = ActiveRecordModel.GetModel(hierarchy.Type.BaseType);
			}

			hierarchy = model;

			while(hierarchy != null)
			{
				foreach(NestedModel nested in hierarchy.Components)
				{
					object nestedInstance = nested.Property.GetValue(instance, null);

					if (nestedInstance == null)
					{
						nestedInstance = CreationUtil.Create(nested.Property.PropertyType);
					}

					if (nestedInstance != null)
					{
						model2nestedInstance[nested.Model] = nestedInstance;
					}

					list.Add(nested.Model);
				}

				hierarchy = ActiveRecordModel.GetModel(hierarchy.Type.BaseType);
			}

			return list;
		}
        private static bool IsChildClass(ActiveRecordModel model, ActiveRecordModel child)
        {
            // generic check
            if (child.Type.BaseType.IsGenericType)
            {
                var baseType = child.Type.BaseType;
                while (baseType != null && baseType.IsGenericType)
                {
                    if (baseType.GetGenericTypeDefinition() == model.Type)
                    {
                        return(true);
                    }
                    baseType = baseType.BaseType;
                }
            }

            // Direct decendant
            if (child.Type.BaseType == model.Type)
            {
                return(true);
            }

            // Not related to each other
            if (!model.Type.IsAssignableFrom(child.Type))
            {
                return(false);
            }

            // The model is the ancestor of the child, but is it the direct AR ancestor?
            Type arAncestor = child.Type.BaseType;

            while (arAncestor != typeof(object) && ActiveRecordModel.GetModel(arAncestor) == null)
            {
                arAncestor = arAncestor.BaseType;
            }

            return(arAncestor == model.Type);
        }
예제 #40
0
        private static void PopulateActiveRecordAttribute(ActiveRecordAttribute attribute, ActiveRecordModel model)
        {
            model.ActiveRecordAtt = attribute;

            if (attribute.DiscriminatorColumn != null)
            {
                model.IsDiscriminatorBase = true;

                if (attribute.DiscriminatorValue == null)
                {
                    throw new ActiveRecordException(
                              String.Format("You must specify a discriminator value for the type {0}", model.Type.FullName));
                }
            }
            else if (attribute.DiscriminatorType != null)
            {
                throw new ActiveRecordException(
                          String.Format("The usage of DiscriminatorType for {0} is meaningless", model.Type.FullName));
            }

            if (model.ActiveRecordAtt.Table == null)
            {
                string safename = GetSafeName(model.Type.Name);
                model.ActiveRecordAtt.Table = ActiveRecordModel.pluralizeTableNames
                                                                                                ? Inflector.Pluralize(safename)
                                                                                                : safename;
            }
        }
		private static void ProcessProperties(Type type, ActiveRecordModel model)
		{
			// Check persistent properties of the base class as well
			if (ShouldCheckBase(type))
			{
				ProcessProperties(type.BaseType, model);
			}

			PropertyInfo[] props = type.GetProperties(DefaultBindingFlags);

			foreach (PropertyInfo prop in props)
			{
				bool isArProperty = false;
				AnyModel anyModel;
				HasManyToAnyModel hasManyToAnyModel;

				object[] valAtts = prop.GetCustomAttributes(typeof(AbstractValidationAttribute), true);

				foreach (AbstractValidationAttribute valAtt in valAtts)
				{
					IValidator validator = valAtt.Build();
					validator.Initialize(validatorRegistry, prop);

					model.Validators.Add(validator);
				}

				foreach (object attribute in prop.GetCustomAttributes(false))
				{
					if (attribute is PrimaryKeyAttribute)
					{
						PrimaryKeyAttribute propAtt = attribute as PrimaryKeyAttribute;
						isArProperty = true;

						// Joined Subclasses must not have PrimaryKey
						if (type.IsDefined(typeof(JoinedBaseAttribute), true) && // JoinedBase in a superclass
							!type.IsDefined(typeof(JoinedBaseAttribute), false)) // but not here
						{
							throw new ActiveRecordException("You can't specify a PrimaryKeyAttribute in a joined subclass. " +
															"Check type " + model.Type.FullName);
						}

						if (prop.PropertyType.IsDefined(typeof(CompositeKeyAttribute), true))
						{
							object[] att = prop.PropertyType.GetCustomAttributes(typeof(CompositeKeyAttribute), true);

							CompositeKeyAttribute cAtt = att[0] as CompositeKeyAttribute;

							model.CompositeKey = new CompositeKeyModel(prop, cAtt);
						}
						else
						{
							model.PrimaryKey = new PrimaryKeyModel(prop, propAtt);
						}
					}
					else if (attribute is CompositeKeyAttribute)
					{
						CompositeKeyAttribute propAtt = attribute as CompositeKeyAttribute;
						isArProperty = true;

						model.CompositeKey = new CompositeKeyModel(prop, propAtt);
					}
					else if (attribute is AnyAttribute)
					{
						AnyAttribute anyAtt = attribute as AnyAttribute;
						isArProperty = true;
						anyModel = new AnyModel(prop, anyAtt);
						model.Anys.Add(anyModel);

						CollectMetaValues(anyModel.MetaValues, prop);
					}
					else if (attribute is PropertyAttribute)
					{
						PropertyAttribute propAtt = attribute as PropertyAttribute;
						isArProperty = true;

						model.Properties.Add(new PropertyModel(prop, propAtt));
					}
					else if (attribute is NestedAttribute)
					{
						NestedAttribute propAtt = attribute as NestedAttribute;
						isArProperty = true;

						ActiveRecordModel nestedModel = new ActiveRecordModel(prop.PropertyType);

						nestedModel.IsNestedType = true;

						Type nestedType = propAtt.MapType != null ? propAtt.MapType : prop.PropertyType;
						nestedModel.IsNestedCompositeType = model.IsNestedCompositeType;
						ProcessProperties(nestedType, nestedModel);
						ProcessFields(nestedType, nestedModel);

						model.Components.Add(new NestedModel(prop, propAtt, nestedModel));
					}
					else if (attribute is NestedParentReferenceAttribute)
					{
						NestedParentReferenceAttribute nestedParentAtt = attribute as NestedParentReferenceAttribute;
						isArProperty = true;

						model.ComponentParent.Add(new NestedParentReferenceModel(prop, nestedParentAtt));
					}
					else if (attribute is JoinedKeyAttribute)
					{
						JoinedKeyAttribute propAtt = attribute as JoinedKeyAttribute;
						isArProperty = true;

						if (model.Key != null)
						{
							throw new ActiveRecordException("You can't specify more than one JoinedKeyAttribute. " +
															"Check type " + model.Type.FullName);
						}

						model.Key = new KeyModel(prop, propAtt);
					}
					else if (attribute is VersionAttribute)
					{
						VersionAttribute propAtt = attribute as VersionAttribute;
						isArProperty = true;

						if (model.Version != null)
						{
							throw new ActiveRecordException("You can't specify more than one VersionAttribute. " +
															"Check type " + model.Type.FullName);
						}

						model.Version = new VersionModel(prop, propAtt);
					}
					else if (attribute is TimestampAttribute)
					{
						TimestampAttribute propAtt = attribute as TimestampAttribute;
						isArProperty = true;

						if (model.Timestamp != null)
						{
							throw new ActiveRecordException("You can't specify more than one TimestampAttribute. " +
															"Check type " + model.Type.FullName);
						}

						model.Timestamp = new TimestampModel(prop, propAtt);
					}
					// Relations
					else if (attribute is OneToOneAttribute)
					{
						OneToOneAttribute propAtt = attribute as OneToOneAttribute;
						isArProperty = true;

						model.OneToOnes.Add(new OneToOneModel(prop, propAtt));
					}
					else if (attribute is BelongsToAttribute)
					{
						BelongsToAttribute propAtt = attribute as BelongsToAttribute;
						isArProperty = true;

						model.BelongsTo.Add(new BelongsToModel(prop, propAtt));
					}
					// The ordering is important here, HasManyToAny must comes before HasMany!
					else if (attribute is HasManyToAnyAttribute)
					{
						HasManyToAnyAttribute propAtt = attribute as HasManyToAnyAttribute;
						isArProperty = true;

						hasManyToAnyModel = new HasManyToAnyModel(prop, propAtt);
						model.HasManyToAny.Add(hasManyToAnyModel);

						CollectMetaValues(hasManyToAnyModel.MetaValues, prop);
					}
					else if (attribute is HasManyAttribute)
					{
						HasManyAttribute propAtt = attribute as HasManyAttribute;
						isArProperty = true;

						HasManyModel hasManyModel = new HasManyModel(prop, propAtt);
						if (propAtt.DependentObjects)
						{
							ActiveRecordModel dependentObjectModel = new ActiveRecordModel(propAtt.MapType);
							dependentObjectModel.IsNestedType = true;
							dependentObjectModel.IsNestedCompositeType = true;
							ProcessProperties(propAtt.MapType, dependentObjectModel);

							hasManyModel.DependentObjectModel = new DependentObjectModel(prop, propAtt, dependentObjectModel);
						}
						model.HasMany.Add(hasManyModel);
					}
					else if (attribute is HasAndBelongsToManyAttribute)
					{
						HasAndBelongsToManyAttribute propAtt = attribute as HasAndBelongsToManyAttribute;
						isArProperty = true;

						model.HasAndBelongsToMany.Add(new HasAndBelongsToManyModel(prop, propAtt));
					}
					else if (attribute is Any.MetaValueAttribute)
					{
						if (prop.GetCustomAttributes(typeof(HasManyToAnyAttribute), false).Length == 0 &&
							prop.GetCustomAttributes(typeof(AnyAttribute), false).Length == 0
							)
							throw new ActiveRecordException(
								"You can't specify an Any.MetaValue without specifying the Any or HasManyToAny attribute. " +
								"Check type " + prop.DeclaringType.FullName);
					}
					else if (attribute is CompositeUserTypeAttribute)
					{
						CompositeUserTypeAttribute propAtt = attribute as CompositeUserTypeAttribute;
						isArProperty = true;

						model.CompositeUserType.Add(new CompositeUserTypeModel(prop, propAtt));
					}

					if (attribute is CollectionIDAttribute)
					{
						CollectionIDAttribute propAtt = attribute as CollectionIDAttribute;

						model.CollectionIDs.Add(new CollectionIDModel(prop, propAtt));
					}
					if (attribute is HiloAttribute)
					{
						HiloAttribute propAtt = attribute as HiloAttribute;

						model.Hilos.Add(new HiloModel(prop, propAtt));
					}
				}

				if (!isArProperty)
				{
					model.NotMappedProperties.Add(prop);
				}
			}
		}
		private static void ProcessFields(Type type, ActiveRecordModel model)
		{
			//Check persistent fields of the base class as well
			if (ShouldCheckBase(type))
			{
				ProcessFields(type.BaseType, model);
			}

			FieldInfo[] fields = type.GetFields(FieldDefaultBindingFlags);

			foreach (FieldInfo field in fields)
			{
				if (field.IsDefined(typeof(FieldAttribute), false))
				{
					FieldAttribute fieldAtt = field.GetCustomAttributes(typeof(FieldAttribute), false)[0] as FieldAttribute;

					model.Fields.Add(new FieldModel(field, fieldAtt));
				}
			}
		}
		private static void PopulateActiveRecordAttribute(ActiveRecordAttribute attribute, ActiveRecordModel model)
		{
			model.ActiveRecordAtt = attribute;

			if (attribute.DiscriminatorColumn != null)
			{
				model.IsDiscriminatorBase = true;

				if (attribute.DiscriminatorValue == null)
				{
					throw new ActiveRecordException(
						String.Format("You must specify a discriminator value for the type {0}", model.Type.FullName));
				}
			}
			else if (attribute.DiscriminatorType != null)
			{
				throw new ActiveRecordException(
					String.Format("The usage of DiscriminatorType for {0} is meaningless", model.Type.FullName));
			}

			if (model.ActiveRecordAtt.Table == null)
			{
				string safename = GetSafeName(model.Type.Name);
				model.ActiveRecordAtt.Table = ActiveRecordModel.pluralizeTableNames
												? Inflector.Pluralize(safename)
												: safename;
			}
		}
예제 #44
0
		/// <summary>
		/// for joined subclasses BelongsTo properties doesn't include the ones of the parent class
		/// so we need to check them recursively
		/// </summary>
		protected bool IsBelongsToRef(ActiveRecordModel arModel, string prefix)
		{
			foreach(var model in arModel.BelongsTo)
			{
				if (model.Property.Name == prefix)
				{
					return true;
				}
			}
			if (arModel.IsJoinedSubClass || arModel.IsDiscriminatorSubClass)
			{
				return IsBelongsToRef(arModel.Parent, prefix);
			}
			return false;
		}
		private static bool IsChildClass(ActiveRecordModel model, ActiveRecordModel child)
		{
			// generic check
			if (child.Type.BaseType.IsGenericType)
			{
				var baseType = child.Type.BaseType;
				while (baseType != null && baseType.IsGenericType)
				{
					if (baseType.GetGenericTypeDefinition() == model.Type) return true;
					baseType = baseType.BaseType;
				}
			}

			// Direct decendant
			if (child.Type.BaseType == model.Type) return true;

			// Not related to each other
			if (!model.Type.IsAssignableFrom(child.Type)) return false;

			// The model is the ancestor of the child, but is it the direct AR ancestor?
			Type arAncestor = child.Type.BaseType;

			while(arAncestor != typeof(object) && ActiveRecordModel.GetModel(arAncestor) == null)
			{
				arAncestor = arAncestor.BaseType;
			}

			return arAncestor == model.Type;
		}
		private static void ProcessImports(Type type, ActiveRecordModel model)
		{
			object[] attrs = type.GetCustomAttributes(typeof(ImportAttribute), false);

			foreach (ImportAttribute att in attrs)
			{
				ImportModel im = new ImportModel(att);
				model.Imports.Add(im);
			}
		}
		/// <summary>
		/// Dispatches the call to the extensions.
		/// </summary>
		/// <param name="pi">The property info reflection object.</param>
		/// <param name="hasManyModel">The has many model.</param>
		/// <param name="model">The model.</param>
		public void ProcessHasMany(PropertyInfo pi, HasManyModel hasManyModel, ActiveRecordModel model)
		{
			foreach(IModelBuilderExtension extension in extensions)
			{
				extension.ProcessHasMany(pi, hasManyModel, model);
			}
		}
        public override void VisitHasMany(HasManyModel model)
        {
            model.HasManyAtt.RelationType = GuessRelation(model.Property, model.HasManyAtt.RelationType);

            if (model.HasManyAtt.RelationType == RelationType.IdBag)
            {
                throw new ActiveRecordException(String.Format(
                                                    "You can't use idbags in a many to one association (HasMany) {0}.{1}  ",
                                                    model.Property.DeclaringType.Name, model.Property.Name));
            }

            if (model.HasManyAtt.RelationType == RelationType.Map && model.HasManyAtt.Index == null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "A HasMany with type Map requires that you specify an 'Index', use the Index property {0}.{1}  ",
                                                    model.Property.DeclaringType.Name, model.Property.Name));
            }

            // Infer table and column based on possible belongs to
            // on the target class

            String table     = model.HasManyAtt.Table;
            String keyColumn = model.HasManyAtt.ColumnKey;

            ActiveRecordModel target = arCollection[model.HasManyAtt.MapType];

            if ((table == null || keyColumn == null) && target == null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "ActiveRecord tried to infer details about the relation {0}.{1} but " +
                                                    "it could not find information about the specified target type {2}",
                                                    model.Property.DeclaringType.Name, model.Property.Name, model.HasManyAtt.MapType));
            }

            BelongsToModel targetBtModel = null;

            if (target != null)
            {
                foreach (BelongsToModel btModel in target.BelongsTo)
                {
                    if (btModel.BelongsToAtt.Type == model.Property.DeclaringType ||
                        btModel.Property.PropertyType == model.Property.DeclaringType)
                    {
                        targetBtModel = btModel; break;
                    }
                }
            }

            if ((table == null || keyColumn == null) && targetBtModel == null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "ActiveRecord tried to infer details about the relation {0}.{1} but " +
                                                    "it could not find a 'BelongsTo' mapped property in the target type {2}",
                                                    model.Property.DeclaringType.Name, model.Property.Name, model.HasManyAtt.MapType));
            }

            if (target != null)
            {
                VisitModel(target);
            }

            if (table == null)
            {
                table = target.ActiveRecordAtt.Table;
            }

            if (keyColumn == null)
            {
                keyColumn = targetBtModel.BelongsToAtt.Column;
            }

            model.HasManyAtt.Table     = table;
            model.HasManyAtt.ColumnKey = keyColumn;
        }
        public override void VisitProperty(PropertyModel model)
        {
            if (model.PropertyAtt.Column == null)
            {
                model.PropertyAtt.Column = model.Property.Name;
            }

            if (typeof(INullableType).IsAssignableFrom(model.Property.PropertyType))
            {
                model.PropertyAtt.NotNull = false;

                if (model.Property.PropertyType == typeof(NullableBoolean))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableBooleanType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableByte))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableByteType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableChar))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableCharType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableDateTime))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableDateTimeType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableDecimal))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableDecimalType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableDouble))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableDoubleType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableGuid))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableGuidType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableInt16))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableInt16Type, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableInt32))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableInt32Type, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableInt64))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableInt64Type, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableSByte))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableSByteType, Nullables.NHibernate";
                }
                else if (model.Property.PropertyType == typeof(NullableSingle))
                {
                    model.PropertyAtt.ColumnType = "Nullables.NHibernate.NullableSingleType, Nullables.NHibernate";
                }
            }
            if (ActiveRecordModel.GetModel(model.Property.PropertyType) != null)
            {
                throw new ActiveRecordException(String.Format(
                                                    "You can't use [Property] on {0}.{1} because {2} is an active record class, did you mean to use BelongTo?",
                                                    model.Property.DeclaringType.Name, model.Property.Name, model.Property.PropertyType.FullName));
            }
        }
예제 #50
0
        private void ProcessProperties(Type type, ActiveRecordModel model)
        {
            // Check persistent properties of the base class as well
            if (ShouldCheckBase(type))
            {
                ProcessProperties(type.BaseType, model);
            }

            PropertyInfo[] props = type.GetProperties(DefaultBindingFlags);

            foreach (PropertyInfo prop in props)
            {
                bool              isArProperty = false;
                AnyModel          anyModel;
                HasManyToAnyModel hasManyToAnyModel;

                if (extension != null)
                {
                    extension.ProcessProperty(prop, model);
                }

                object[] valAtts = prop.GetCustomAttributes(typeof(AbstractValidationAttribute), true);

                foreach (AbstractValidationAttribute valAtt in valAtts)
                {
                    IValidator validator = valAtt.Build();
                    validator.Initialize(validatorRegistry, prop);

                    model.Validators.Add(validator);
                }

                foreach (object attribute in prop.GetCustomAttributes(false))
                {
                    if (attribute is PrimaryKeyAttribute)
                    {
                        PrimaryKeyAttribute propAtt = attribute as PrimaryKeyAttribute;
                        isArProperty = true;

                        // Joined Subclasses must not have PrimaryKey
                        if (HasJoinedBase(type))
                        {
                            throw new ActiveRecordException("You can't specify a PrimaryKeyAttribute in a joined subclass. " +
                                                            "Check type " + model.Type.FullName);
                        }

                        if (prop.PropertyType.IsDefined(typeof(CompositeKeyAttribute), true))
                        {
                            object[] att = prop.PropertyType.GetCustomAttributes(typeof(CompositeKeyAttribute), true);

                            CompositeKeyAttribute cAtt = att[0] as CompositeKeyAttribute;

                            model.CompositeKey = new CompositeKeyModel(prop, cAtt);
                        }
                        else
                        {
                            if (!propAtt.IsOverride && model.PrimaryKey != null)
                            {
                                throw new ActiveRecordException("You can't specify more than one PrimaryKeyAttribute in a " +
                                                                "class. Check type " + model.Type.FullName);
                            }

                            model.PrimaryKey = new PrimaryKeyModel(prop, propAtt);
                        }
                    }
                    else if (attribute is CompositeKeyAttribute)
                    {
                        CompositeKeyAttribute propAtt = attribute as CompositeKeyAttribute;
                        isArProperty = true;

                        model.CompositeKey = new CompositeKeyModel(prop, propAtt);
                    }
                    else if (attribute is AnyAttribute)
                    {
                        AnyAttribute anyAtt = attribute as AnyAttribute;
                        isArProperty = true;
                        anyModel     = new AnyModel(prop, anyAtt);
                        model.Anys.Add(anyModel);

                        CollectMetaValues(anyModel.MetaValues, prop);
                    }
                    else if (attribute is PropertyAttribute)
                    {
                        PropertyAttribute propAtt = attribute as PropertyAttribute;
                        isArProperty = true;

                        // If this property overrides a base class property remove the old one
                        if (propAtt.IsOverride)
                        {
                            for (int index = 0; index < model.Properties.Count; ++index)
                            {
                                PropertyModel oldModel = (PropertyModel)model.Properties[index];

                                if (oldModel.Property.Name == prop.Name)
                                {
                                    model.Properties.RemoveAt(index);
                                    break;
                                }
                            }
                        }

                        PropertyModel propModel = new PropertyModel(prop, propAtt);
                        model.Properties.Add(propModel);
                        model.PropertyDictionary[prop.Name] = propModel;
                    }
                    else if (attribute is NestedAttribute)
                    {
                        NestedAttribute propAtt = attribute as NestedAttribute;
                        isArProperty = true;

                        ActiveRecordModel nestedModel = new ActiveRecordModel(prop.PropertyType);

                        nestedModel.IsNestedType = true;

                        Type nestedType = propAtt.MapType ?? prop.PropertyType;
                        nestedModel.IsNestedCompositeType = model.IsNestedCompositeType;
                        ProcessProperties(nestedType, nestedModel);
                        ProcessFields(nestedType, nestedModel);

                        NestedModel nested = new NestedModel(prop, propAtt, nestedModel);
                        nestedModel.ParentNested = nested;

                        model.Components.Add(nested);
                    }
                    else if (attribute is NestedParentReferenceAttribute)
                    {
                        NestedParentReferenceAttribute nestedParentAtt = attribute as NestedParentReferenceAttribute;
                        isArProperty = true;

                        model.ComponentParent.Add(new NestedParentReferenceModel(prop, nestedParentAtt));
                    }
                    else if (attribute is JoinedKeyAttribute)
                    {
                        JoinedKeyAttribute propAtt = attribute as JoinedKeyAttribute;
                        isArProperty = true;

                        if (model.Key != null)
                        {
                            throw new ActiveRecordException("You can't specify more than one JoinedKeyAttribute. " +
                                                            "Check type " + model.Type.FullName);
                        }

                        model.Key = new KeyModel(prop, propAtt);
                    }
                    else if (attribute is VersionAttribute)
                    {
                        VersionAttribute propAtt = attribute as VersionAttribute;
                        isArProperty = true;

                        if (model.Version != null)
                        {
                            throw new ActiveRecordException("You can't specify more than one VersionAttribute. " +
                                                            "Check type " + model.Type.FullName);
                        }

                        model.Version = new VersionModel(prop, propAtt);
                    }
                    else if (attribute is TimestampAttribute)
                    {
                        TimestampAttribute propAtt = attribute as TimestampAttribute;
                        isArProperty = true;

                        if (model.Timestamp != null)
                        {
                            throw new ActiveRecordException("You can't specify more than one TimestampAttribute. " +
                                                            "Check type " + model.Type.FullName);
                        }

                        model.Timestamp = new TimestampModel(prop, propAtt);
                    }
                    // Relations
                    else if (attribute is OneToOneAttribute)
                    {
                        OneToOneAttribute propAtt = attribute as OneToOneAttribute;
                        isArProperty = true;

                        model.OneToOnes.Add(new OneToOneModel(prop, propAtt));
                    }
                    else if (attribute is BelongsToAttribute)
                    {
                        BelongsToAttribute propAtt = attribute as BelongsToAttribute;
                        isArProperty = true;

                        BelongsToModel btModel = new BelongsToModel(prop, propAtt);
                        model.BelongsTo.Add(btModel);
                        model.BelongsToDictionary[prop.Name] = btModel;

                        if (extension != null)
                        {
                            extension.ProcessBelongsTo(prop, btModel, model);
                        }
                    }
                    // The ordering is important here, HasManyToAny must comes before HasMany!
                    else if (attribute is HasManyToAnyAttribute)
                    {
                        HasManyToAnyAttribute propAtt = attribute as HasManyToAnyAttribute;
                        isArProperty = true;

                        hasManyToAnyModel = new HasManyToAnyModel(prop, propAtt);
                        model.HasManyToAny.Add(hasManyToAnyModel);
                        model.HasManyToAnyDictionary[prop.Name] = hasManyToAnyModel;

                        CollectMetaValues(hasManyToAnyModel.MetaValues, prop);

                        if (extension != null)
                        {
                            extension.ProcessHasManyToAny(prop, hasManyToAnyModel, model);
                        }
                    }
                    else if (attribute is HasManyAttribute)
                    {
                        HasManyAttribute propAtt = attribute as HasManyAttribute;
                        isArProperty = true;

                        HasManyModel hasManyModel = new HasManyModel(prop, propAtt, model);
                        if (propAtt.DependentObjects)
                        {
                            ActiveRecordModel dependentObjectModel = new ActiveRecordModel(propAtt.MapType);
                            dependentObjectModel.IsNestedType          = true;
                            dependentObjectModel.IsNestedCompositeType = true;
                            ProcessProperties(propAtt.MapType, dependentObjectModel);

                            hasManyModel.DependentObjectModel = new DependentObjectModel(prop, propAtt, dependentObjectModel);
                        }
                        model.HasMany.Add(hasManyModel);
                        model.HasManyDictionary[prop.Name] = hasManyModel;

                        if (extension != null)
                        {
                            extension.ProcessHasMany(prop, hasManyModel, model);
                        }
                    }
                    else if (attribute is HasAndBelongsToManyAttribute)
                    {
                        HasAndBelongsToManyAttribute propAtt = attribute as HasAndBelongsToManyAttribute;
                        isArProperty = true;

                        HasAndBelongsToManyModel habtManyModel = new HasAndBelongsToManyModel(prop, propAtt);
                        model.HasAndBelongsToMany.Add(habtManyModel);
                        model.HasAndBelongsToManyDictionary[prop.Name] = habtManyModel;

                        if (extension != null)
                        {
                            extension.ProcessHasAndBelongsToMany(prop, habtManyModel, model);
                        }
                    }
                    else if (attribute is Any.MetaValueAttribute)
                    {
                        if (prop.GetCustomAttributes(typeof(HasManyToAnyAttribute), false).Length == 0 &&
                            prop.GetCustomAttributes(typeof(AnyAttribute), false).Length == 0
                            )
                        {
                            throw new ActiveRecordException(
                                      "You can't specify an Any.MetaValue without specifying the Any or HasManyToAny attribute. " +
                                      "Check type " + prop.DeclaringType.FullName);
                        }
                    }
                    else if (attribute is CompositeUserTypeAttribute)
                    {
                        CompositeUserTypeAttribute propAtt = attribute as CompositeUserTypeAttribute;
                        isArProperty = true;

                        model.CompositeUserType.Add(new CompositeUserTypeModel(prop, prop.PropertyType, propAtt));
                    }

                    if (attribute is CollectionIDAttribute)
                    {
                        CollectionIDAttribute propAtt = attribute as CollectionIDAttribute;

                        model.CollectionIDs.Add(new CollectionIDModel(prop, propAtt));
                    }
                    if (attribute is HiloAttribute)
                    {
                        HiloAttribute propAtt = attribute as HiloAttribute;

                        model.Hilos.Add(new HiloModel(prop, propAtt));
                    }
                }

                if (!isArProperty)
                {
                    model.NotMappedProperties.Add(prop);
                }
            }
        }
 ///<summary>
 /// Initializes a new instance of the <see cref="DependentObjectModel"/> class.
 ///</summary>
 /// <param name="propInfo">The prop info.</param>
 /// <param name="hasManyAtt">The nested att.</param>
 /// <param name="dependentObjectModel">The nested model.</param>
 public DependentObjectModel(PropertyInfo propInfo, HasManyAttribute hasManyAtt, ActiveRecordModel dependentObjectModel)
 {
     this.dependentObjectModel = dependentObjectModel;
     this.hasManyAtt           = hasManyAtt;
 }
예제 #52
0
		private object ObtainPrimaryKeyValue(ActiveRecordModel model, CompositeNode node, String prefix,
											 out PrimaryKeyModel pkModel)
		{
			pkModel = ObtainPrimaryKey(model);

			var pkPropName = pkModel.Property.Name;

			var idNode = node.GetChildNode(pkPropName);

			if (idNode == null) return null;

			if (idNode != null && idNode.NodeType != NodeType.Leaf)
			{
				throw new BindingException("Expecting leaf node to contain id for ActiveRecord class. " +
										   "Prefix: {0} PK Property Name: {1}", prefix, pkPropName);
			}

			var lNode = (LeafNode) idNode;

			if (lNode == null)
			{
				throw new BindingException("ARDataBinder autoload failed as element {0} " +
										   "doesn't have a primary key {1} value", prefix, pkPropName);
			}

			bool conversionSuc;

			return Converter.Convert(pkModel.Property.PropertyType, lNode.ValueType, lNode.Value, out conversionSuc);
		}
		private static void ProcessActiveRecordAttribute(Type type, ActiveRecordModel model)
		{
			object[] attrs = type.GetCustomAttributes(typeof(ActiveRecordAttribute), false);

			if (attrs.Length == 0)
			{
				throw new ActiveRecordException(
					String.Format("Type {0} is not using the ActiveRecordAttribute, which is obligatory.", type.FullName));
			}

			ActiveRecordAttribute arAttribute = attrs[0] as ActiveRecordAttribute;

			PopulateActiveRecordAttribute(arAttribute, model);
		}
예제 #54
0
 public override void VisitModel(ActiveRecordModel model)
 {
     if (model.IsJoinedSubClass)
     {
         AppendF("<joined-subclass {0} {1} {2} {3} {4}>",
                 MakeAtt("name", MakeTypeName(model.Type)),
                 MakeAtt("table", model.ActiveRecordAtt.Table),
                 WriteIfNonNull("schema", model.ActiveRecordAtt.Schema),
                 WriteIfNonNull("proxy", MakeTypeName(model.ActiveRecordAtt.Proxy)),
                 WriteIfNonNull("discriminator-value", model.ActiveRecordAtt.DiscriminatorValue));
         Ident();
         VisitNode(model.Key);
         VisitNodes(model.Fields);
         VisitNodes(model.Properties);
         VisitNodes(model.BelongsTo);
         VisitNodes(model.HasMany);
         VisitNodes(model.HasManyToAny);
         VisitNodes(model.HasAndBelongsToMany);
         VisitNodes(model.Components);
         VisitNodes(model.OneToOnes);
         VisitNodes(model.JoinedClasses);
         VisitNodes(model.Classes);
         Dedent();
         Append("</joined-subclass>");
     }
     else if (model.IsDiscriminatorSubClass)
     {
         AppendF("<subclass {0} {1} {2}>",
                 MakeAtt("name", MakeTypeName(model.Type)),
                 WriteIfNonNull("proxy", MakeTypeName(model.ActiveRecordAtt.Proxy)),
                 MakeAtt("discriminator-value", model.ActiveRecordAtt.DiscriminatorValue));
         Ident();
         VisitNodes(model.Fields);
         VisitNodes(model.Properties);
         VisitNodes(model.BelongsTo);
         VisitNodes(model.HasMany);
         VisitNodes(model.HasManyToAny);
         VisitNodes(model.HasAndBelongsToMany);
         VisitNodes(model.Components);
         VisitNodes(model.OneToOnes);
         VisitNodes(model.JoinedClasses);
         VisitNodes(model.Classes);
         Dedent();
         Append("</subclass>");
     }
     else if (model.IsNestedType)
     {
         Ident();
         VisitNodes(model.Fields);
         VisitNodes(model.Properties);
         VisitNodes(model.BelongsTo);
         VisitNodes(model.HasMany);
         VisitNodes(model.HasManyToAny);
         VisitNodes(model.HasAndBelongsToMany);
         VisitNodes(model.Components);
         VisitNodes(model.OneToOnes);
         Dedent();
     }
     else
     {
         AppendF("<class {0} {1} {2} {3} {4} {5} {6}>",
                 MakeAtt("name", MakeTypeName(model.Type)),
                 MakeAtt("table", model.ActiveRecordAtt.Table),
                 WriteIfNonNull("discriminator-value", model.ActiveRecordAtt.DiscriminatorValue),
                 WriteIfNonNull("schema", model.ActiveRecordAtt.Schema),
                 WriteIfNonNull("proxy", MakeTypeName(model.ActiveRecordAtt.Proxy)),
                 WriteIfNonNull("where", model.ActiveRecordAtt.Where),
                 WriteIfTrue("lazy", model.ActiveRecordAtt.Lazy));
         Ident();
         EnsureOnlyOneKey(model);
         WriteCache(model.ActiveRecordAtt.Cache);
         VisitNodes(model.Ids);
         WriteDiscriminator(model);
         VisitNode(model.Version);
         VisitNode(model.Timestamp);
         VisitNodes(model.Fields);
         VisitNodes(model.Properties);
         VisitNodes(model.Anys);
         VisitNodes(model.BelongsTo);
         VisitNodes(model.HasMany);
         VisitNodes(model.HasManyToAny);
         VisitNodes(model.HasAndBelongsToMany);
         VisitNodes(model.Components);
         VisitNodes(model.OneToOnes);
         VisitNodes(model.JoinedClasses);
         VisitNodes(model.Classes);
         Dedent();
         Append("</class>");
     }
 }
예제 #55
0
 private static void ProcessJoinedBaseAttribute(Type type, ActiveRecordModel model)
 {
     model.IsJoinedSubClassBase = type.IsDefined(typeof(JoinedBaseAttribute), false);
 }
예제 #56
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HasManyModel"/> class.
 /// </summary>
 /// <param name="propInfo">The prop info.</param>
 /// <param name="hasManyAtt">The has many att.</param>
 /// <param name="containingTypeModel">The model for the type that contains the HasMany reference.</param>
 public HasManyModel(PropertyInfo propInfo, HasManyAttribute hasManyAtt, ActiveRecordModel containingTypeModel)
 {
     this.hasManyAtt          = hasManyAtt;
     this.propInfo            = propInfo;
     this.containingTypeModel = containingTypeModel;
 }
예제 #57
0
 public NestedModel(PropertyInfo propInfo, NestedAttribute nestedAtt, ActiveRecordModel nestedModel)
 {
     this.nestedAtt   = nestedAtt;
     this.nestedModel = nestedModel;
     this.propInfo    = propInfo;
 }
		private static void ProcessJoinedBaseAttribute(Type type, ActiveRecordModel model)
		{
			model.IsJoinedSubClassBase = type.IsDefined(typeof(JoinedBaseAttribute), false);
		}
예제 #59
0
		private static PrimaryKeyModel ObtainPrimaryKey(ActiveRecordModel model)
		{
			if (model.IsJoinedSubClass || model.IsDiscriminatorSubClass)
			{
				return ObtainPrimaryKey(model.Parent);
			}
			return model.PrimaryKey;
		}
예제 #60
0
		/// <summary>
		/// for joined subclasses HasMany properties doesn't include the ones of the parent class
		/// so we need to check them recursively
		/// </summary>
		protected bool FindPropertyInHasMany(ActiveRecordModel model, string propertyName,
											 ref Type foundType, ref ActiveRecordModel foundModel)
		{
			foreach(var hasManyModel in model.HasMany)
			{
				// Inverse=true relations will be ignored
				if (hasManyModel.Property.Name == propertyName && !hasManyModel.HasManyAtt.Inverse)
				{
					foundType = hasManyModel.HasManyAtt.MapType;
					foundModel = ActiveRecordModel.GetModel(foundType);
					return true;
				}
			}
			if (model.IsJoinedSubClass || model.IsDiscriminatorSubClass)
			{
				return FindPropertyInHasMany(model.Parent, propertyName, ref foundType, ref foundModel);
			}
			return false;
		}