예제 #1
0
		public ValidationMap( ObjectMap map, string propertyName, Type propertyType, ValidatorBaseAttribute va )
		{
			this.map = map;
			this.propertyName = propertyName;
			this.propertyType = propertyType;
			this.va = va;
		}
예제 #2
0
		public ObjectConstructor( ObjectMap objectMap )
		{
			this.objectMap = objectMap;
			constructorInfos = Reflector.FindConstructors( objectMap.Type );
			constructorMaps = new Hashtable();
			columnInfos = new Hashtable();
		}
예제 #3
0
		public ConstructorMap( ObjectMap objectMap, ConstructorInfo constructorInfo, ColumnInfo columnInfo, object[] row )
		{
			this.objectMap = objectMap;
			this.constructorInfo = constructorInfo;
			this.columnInfo = columnInfo;
			InitBitArrays( Math.Max( objectMap.Fields.Count, row.Length ) );
			InitConstructorMap( row );
		}
예제 #4
0
		protected virtual void InitParent( IPersistent parent )
		{
			Check.VerifyNotNull( parent, Error.NullParameter, "parent" );
			Check.Verify( parent.IsPersisted || ! parentMap.IsAutoGeneratedPrimaryKey, Error.DeveloperError,
			              "The parent object must have been persisted before you can use the list." );
			this.parent = parent;
			parentMap = ObjectFactory.GetMap( broker, parent );
		}
예제 #5
0
		protected virtual void InitType( Type containedType, IPersistent parent, Type viaType )
		{
			containedMap = ObjectFactory.GetMap( broker, containedType );
			Check.Verify( containedType.GetInterface( "IPersistent", false ) != null,
			              Error.UnsupportedType, containedType );
			listType = parent == null
			           	? GentleListType.StandAlone
			           	:
			           		(viaType == null ? GentleListType.OneToMany : GentleListType.ManyToMany);
		}
예제 #6
0
		public ViewMap( ObjectMap map, string propertyName, Type propertyType, CustomViewAttribute cv )
		{
			this.map = map;
			this.propertyName = propertyName;
			this.propertyType = propertyType;
			this.cv = cv;
			if( map != null && cv.NavigateUrlFormat != null )
			{
				string[] keys = map.GetPrimaryKeyNames( true );
				primaryKeyName = keys[ 0 ];
			}
		}
예제 #7
0
		/// <summary>
		/// Create a new list for storing the specified type of objects.
		/// </summary>
		public GentleRelation( PersistenceBroker broker, Type containedType, IPersistent parent,
		                       params Type[] relatedTypes ) : base( broker )
		{
			Check.VerifyNotNull( relatedTypes, Error.NullParameter, "relatedTypes" );
			/*Check.Verify( parent == null && relatedTypes.Length == 2 ||
				parent != null && relatedTypes.Length == 1, Error.NotImplemented,
			              "The GentleRelation class is currently only able to manage two-way relations." ); */
			this.relatedTypes = relatedTypes;
			this.parent = parent;
			containedMap = ObjectFactory.GetMap( broker, containedType );
			// note: "this." required on broker param or original null param might get passed
			relations = new GentleList( this.broker, containedType, parent );
			// verify that the linked types are supported by Gentle
			foreach( Type relatedType in relatedTypes )
			{
				Check.Verify( relatedType.IsSubclassOf( typeof(Persistent) ) || relatedType.GetInterface( "IPersistent" ) != null,
				              Error.UnsupportedType, relatedType );
			}
		}
예제 #8
0
		/// <summary>
		/// Constructor for fields using information obtained from the TableColumn attribute.
		/// </summary>
		public FieldMap( ObjectMap map, MemberAttributeInfo memberAttributeInfo )
		{
			this.map = map;
			memberInfo = memberAttributeInfo.MemberInfo;
			if( memberInfo is PropertyInfo )
			{
				memberType = (memberInfo as PropertyInfo).PropertyType;
			}
			else
			{
				memberType = (memberInfo as FieldInfo).FieldType;
			}
			// extract information from attributes
			if( memberAttributeInfo.Attributes != null )
			{
				foreach( Attribute attr in memberAttributeInfo.Attributes )
				{
					if( attr is TableColumnAttribute )
					{
						TableColumnAttribute tc = attr as TableColumnAttribute;
						SetColumnName( tc.Name ?? memberInfo.Name );
						SetNullValue( tc.NullValue );
						SetIsNullable( ! tc.NotNull );
						SetSize( tc.Size );
						if( tc.HasDbType )
						{
							SetDbType( tc.DatabaseType );
						}
						else
						{
							SetDbType( NO_DBTYPE );
						}
						handleEnumAsString = tc.HandleEnumAsString;
						isReadOnly = tc.IsReadOnly;
						isUpdateAfterWrite = tc.IsUpdateAfterWrite;
					}
					else if( attr is PrimaryKeyAttribute )
					{
						PrimaryKeyAttribute pk = attr as PrimaryKeyAttribute;
						SetIsPrimaryKey( true );
						SetIsAutoGenerated( pk.AutoGenerated );
						if( IsAutoGenerated )
						{
							map.IdentityMap = this;
						}
					}
					else if( attr is ForeignKeyAttribute )
					{
						ForeignKeyAttribute fk = attr as ForeignKeyAttribute;
						SetForeignKeyTableName( fk.ForeignTable );
						SetForeignKeyColumnName( fk.ForeignColumn );
					}
					else if( attr is ConcurrencyAttribute )
					{
						ConcurrencyAttribute ca = attr as ConcurrencyAttribute;
						Check.Verify( memberType == typeof(int) || memberType == typeof(long),
						              Error.DeveloperError, "Unsupported property type {0} for ConcurrencyAttribute {1}",
						              memberInfo.ReflectedType, memberInfo.Name );
						isConcurrencyColumn = true;
						map.ConcurrencyMap = this;
					}
					else if( attr is SoftDeleteAttribute )
					{
						SoftDeleteAttribute sd = attr as SoftDeleteAttribute;
						Check.Verify( memberType == typeof(int) || memberType == typeof(long),
						              Error.DeveloperError, "Unsupported property type {0} for SoftDeleteAttribute {1}",
						              memberInfo.ReflectedType, memberInfo.Name );
						isSoftDeleteColumn = true;
						map.SoftDeleteMap = this;
					}
					else if( attr is SequenceNameAttribute )
					{
						// sequence name used when available (in place of name conventions or autodetected value)
						sequenceName = (attr as SequenceNameAttribute).Name;
					}
					else if( attr is InheritanceAttribute )
					{
						// sequence name used when available (in place of name conventions or autodetected value)
						map.InheritanceMap = this;
					}
				}
			}
		}
예제 #9
0
		/// <summary>
		/// This method assumes that the tableName and identityColumn parameters are passed
		/// in the correct case. 
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details on the
		/// purpose of this method.
		/// </summary>
		/// <param name="sql">The sql string to which we should append</param>
		/// <param name="om">An <see cref="Gentle.Framework.ObjectMap"/> instance of the object for which to retrieve the identity select</param>
		/// <returns>The modified sql string which also retrieves the identity value</returns>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			if( provider.ProviderInformation.Version.Major >= 2 )
			{
				// strip trailing whitespace and statement terminator
				sql = sql.TrimEnd( ' ', ';' );
				string name = om.IdentityMap.ColumnName;
				if( IsReservedWord( name ) )
				{
					name = QuoteReservedWord( name );
				}
				return String.Format( "{0} returns {1}", sql, name );
			}
			else // try to obtain value using sequence name
			{
				// If the second parameter to GEN_ID is 1 a new value will be generated.
				// If the value is 0, the current value is retrieved.
				if( om.IdentityMap.SequenceName != null )
				{
					return String.Format(
						"select GEN_ID({0}, 0) from rdb$database",
						om.IdentityMap.SequenceName );
				}
				else
				{
					return String.Format(
						"select GEN_ID(GEN_{0}_{1}, 0) from rdb$database",
						om.TableName.ToUpper(), om.IdentityMap.ColumnName.ToUpper() );
				}
			}
		}
예제 #10
0
		internal ObjectView( ObjectMap map, string viewName )
		{
			this.map = map;
			this.viewName = viewName;
			viewMaps = new ArrayList();
		}
예제 #11
0
		/// <summary>
		/// Returns a boolean value indicating whether the current key instance contains exactly
		/// the fields compromising the primary key fields of the given type. This is used to 
		/// determine whether a cached statement can be used (non-primary key select statements 
		/// are not cached).
		/// </summary>
		/// <param name="map">The ObjectMap describing a type and its table mapping.</param>
		/// <param name="ignoreConcurrencyColumn"></param>
		/// <returns>True if the key contains only and exactly the primary key fields of the 
		/// given type.</returns>
		public bool IsPrimaryKeyFields( ObjectMap map, bool ignoreConcurrencyColumn )
		{
			// determine expected field count
			int expectedKeyCount = map.PrimaryKeyCount;
			if( GentleSettings.ConcurrencyControl && map.ConcurrencyMap != null &&
			    ! ignoreConcurrencyColumn && ! map.ConcurrencyMap.IsPrimaryKey )
			{
				expectedKeyCount += 1;
			}
			bool result = Count == expectedKeyCount;
			if( result )
			{
				foreach( FieldMap fm in map.Fields )
				{
					string name = isPropertyKeys ? fm.MemberName : fm.ColumnName;
					result &= ! fm.IsPrimaryKey || (fm.IsPrimaryKey && ContainsKey( name ));
				}
			}
			return result;
		}
예제 #12
0
        /// <summary>
        /// Process the given type and construct the corresponding ObjectMap instance.
        /// </summary>
        /// <param name="broker">The PersistenceBroker to use for obtaining metadata on the type. If
        /// null is passed the DefaultProvider will be used.</param>
        /// <param name="type">The type to process.</param>
        /// <returns>An ObjectMap instance describing the type</returns>
        protected static ObjectMap ConstructMap(PersistenceBroker broker, Type type)
        {
            Check.Verify(IsTypeSupported(type), Error.UnsupportedType, type);
            ObjectMap map = new ObjectMap(broker, type);
            // get persistence attributes
            IList memberAttributeInfos = Reflector.FindMembers(Reflector.InstanceCriteria,
                                                               type, false, typeof(TableColumnAttribute),
                                                               typeof(PrimaryKeyAttribute), typeof(ForeignKeyAttribute),
                                                               typeof(ConcurrencyAttribute), typeof(SoftDeleteAttribute),
                                                               typeof(SequenceNameAttribute), typeof(InheritanceAttribute));

            foreach (MemberAttributeInfo mai in memberAttributeInfos)
            {
                map.Fields.Add(new FieldMap(map, mai));
            }
            // get custom view(s)
            memberAttributeInfos = Reflector.FindMembers(Reflector.InstanceCriteria, type, true, typeof(CustomViewAttribute));
            foreach (MemberAttributeInfo mai in memberAttributeInfos)
            {
                if (mai.MemberInfo is PropertyInfo)
                {
                    foreach (CustomViewAttribute cv in mai.Attributes)
                    {
                        PropertyInfo pi = mai.MemberInfo as PropertyInfo;
                        // create a viewmap for this attribute
                        ViewMap vm = new ViewMap(map, pi.Name, pi.PropertyType, cv);
                        // add it to the specified view
                        map.AddViewColumn(cv.ViewName, vm);
                    }
                }
            }
            // get validation(s)
            memberAttributeInfos = Reflector.FindMembers(Reflector.InstanceCriteria, type, false,
                                                         typeof(ValidatorBaseAttribute));
            foreach (MemberAttributeInfo mai in memberAttributeInfos)
            {
                foreach (ValidatorBaseAttribute vb in mai.Attributes)
                {
                    PropertyInfo pi = mai.MemberInfo as PropertyInfo;
                    // create a validation map for this attribute
                    ValidationMap va = new ValidationMap(map, pi.Name, pi.PropertyType, vb);
                    // add it to the specified view
                    map.Validations.Add(va);
                }
            }

            // analyze the actual database schema and update our internal maps accordingly
            if (GentleSettings.AnalyzerLevel != AnalyzerLevel.None)
            {
                if (broker == null)
                {
                    broker = new PersistenceBroker(type);
                }
                IDatabaseAnalyzer da = broker.Provider.GetAnalyzer();
                if (da != null)                  // not all persistence engines may support this
                {
                    da.UpdateObjectMap(map);
                }
            }
            // return the generated object <-> database map
            return(map);
        }
예제 #13
0
		/// <summary>
		/// Create and populate a DataView from the given SqlResult. Columns in the result set
		/// are copied verbatim to the DataView.
		/// </summary>
		/// <param name="sr">The SqlResult used to generate and populate the DataView.</param>
		/// <returns>The new DataView instance</returns>
		public static DataView GetDataView( SqlResult sr )
		{
			DataTable dt = new DataTable();
			ObjectMap map = null;
			if( sr.Statement != null && sr.Statement.Type != null )
			{
				map = ObjectFactory.GetMap( sr.SessionBroker, sr.Statement.Type );
			}
			foreach( string columnName in sr.ColumnNames )
			{
				DataColumn column = new DataColumn( columnName );
				Type type = GetColumnType( columnName, map, sr );
				if( type != null )
				{
					column.DataType = type;
				}
				dt.Columns.Add( column );
			}
			DataRow dr;
			foreach( object[] row in sr.Rows )
			{
				dr = dt.NewRow();
				dr.ItemArray = row;
				dt.Rows.Add( dr );
			}
			return new DataView( dt );
		}
예제 #14
0
		/// <summary>
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details. 
		/// </summary>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			if( provider.ProviderInformation.Version.Major >= 8 )
			{
				return string.Format( "{0}{1} select SCOPE_IDENTITY()", sql, GetStatementTerminator() );
			}
			else
			{
				return string.Format( "{0}{1} select @@IDENTITY", sql, GetStatementTerminator() );
			}
		}
예제 #15
0
		/// <summary>
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details. 
		/// </summary>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			//Jet does not support more than one SQL statement
			//To be executed at the same time
			return "SELECT @@IDENTITY";
			// Access 97/ Jet 3.x does no support the SELECT @@IDENTITY
			//return string.Format( "SELECT max ({0}) from {1}", om.IdentityMap.ColumnName, om.TableName );
		}
예제 #16
0
		/// <summary>
		/// Get the statement for retrieving last inserted row id for auto-generated id columns
		/// </summary>
		/// <param name="sql"></param>
		/// <param name="om">An <see cref="Gentle.Framework.ObjectMap"/> instance of the object for which to retrieve the identity select</param>
		/// <returns></returns>
		public abstract string GetIdentitySelect( string sql, ObjectMap om );
예제 #17
0
		/// <summary>
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details. 
		/// </summary>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			//Jet does not support more than one SQL statement
			//To be executed at the same time
			return "SELECT @@IDENTITY";
		}
예제 #18
0
		/// <summary>
		/// <p>Get the statement for retrieving last inserted row id for auto-generated id columns.</p>
		/// <p>The value of this property varies between different persistence engines.</p>
		/// </summary>
		/// <param name="sql"></param>
		/// <param name="om"></param>
		/// <returns></returns>
		public string GetIdentitySelect( string sql, ObjectMap om )
		{
			if( sf.HasCapability( Capability.BatchQuery ) )
			{
				return sf.GetIdentitySelect( sql, om );
			}
			else
			{
				//Since the persistence engine does not support Batch Command Processing
				//Two seperate commands must be executed.
				//Execute the results of GentleSqlFactory.GetIdentitySelect to get the last inserted row id
				return sql;
			}
		}
예제 #19
0
		/// <summary>
		/// Construct a new SqlBuilder instance for constructing a statement of the given type
		/// for the specified business class type.
		/// </summary>
		/// <param name="provider">The IGentleProvider used to obtain an SqlFactory</param>
		/// <param name="stmtType">The type of SQL statement to construct</param>
		/// <param name="type">The object class to work on</param>
		/// <param name="logicalOperator">The logic operator used with constraints (can be either AND or OR)</param>
		public SqlBuilder( IGentleProvider provider, StatementType stmtType, Type type, LogicalOperator logicalOperator ) :
			base( provider != null ? new PersistenceBroker( provider ) : type != null ? new PersistenceBroker( type ) : null )
		{
			this.provider = provider ?? broker.Provider;
			sf = this.provider.GetSqlFactory();
			cmd = sf.GetCommand();
			this.stmtType = stmtType;
			map = type != null ? ObjectFactory.GetMap( SessionBroker, type ) : null;
			this.logicalOperator = logicalOperator == LogicalOperator.Or ? " or " : " and ";
			fields = new ArrayList(); // list of fields 
			quotedFields = new ArrayList(); // list of fields 
			constraints = new ArrayList(); // list of string constraints
			parameterValues = new Hashtable();
			parameterOrder = new ArrayList();
		}
예제 #20
0
		/// <summary>
		/// Build a persistence engine specific SQL statement for the given object class, using the
		/// class name as table name and properties for columns.
		/// </summary>
		/// <param name="stmtType">Type of statement to produce (select/insert/update/delete)</param>
		/// <param name="tableName">The table name to use in the constructed query or null to use 
		/// the table name associated with the type</param>
		/// <param name="type">The object class/type</param>
		/// <param name="isCollection">For select statements, whether to return a list of items</param>
		/// <returns>An executable SQL statement object</returns>
		public SqlStatement GetStatement( StatementType stmtType, string tableName, Type type, bool isCollection )
		{
			Check.Verify( stmtType != StatementType.Unknown,
			              "You must set the StatementType before obtaining the SqlStatement." );
			Check.Verify( map == null || map.Type == type, Error.DeveloperError,
			              "The type for this statement has already been set." );
			map = ObjectFactory.GetMap( SessionBroker, type );
			this.stmtType = stmtType;
			if( tableName == null || tableName.Equals( String.Empty ) )
			{
				SetTable( type );
			}
			if( stmtType != StatementType.Count )
			{
				// add key field(s) to select clause (and as parameter if not a collection)
				if( stmtType == StatementType.Select )
				{
					AddKeyFields( type, ! isCollection );
				}
				AddFields( type );
				if( stmtType != StatementType.Insert && ! isCollection )
				{
					bool isWithConcurrency = GentleSettings.ConcurrencyControl && ! isCollection;
					isWithConcurrency &= stmtType == StatementType.Update ||
					                     stmtType == StatementType.Delete || stmtType == StatementType.SoftDelete;
					AddConstraints( type, isWithConcurrency );
				}
			}
			// add filtering for soft deleted objects
			if( (stmtType == StatementType.Select || stmtType == StatementType.Count) && map.IsSoftDelete )
			{
				AddConstraint( Operator.NotEquals, map.SoftDeleteMap.QuotedColumnName, -1 );
			}
			// set any previously given parameter values on statement
			if( parameterOrder != null && parameterOrder.Count > 0 )
			{
				int index = 0;
				foreach( string param in parameterOrder )
				{
					object paramValue = parameterValues[ param ];
					// Uwe Kitzmann: if data provider supports positional parameters only, 
					// a call to AsParameter returns a "?" and not the parameter
					// IDataParameter dp = (IDataParameter) cmd.Parameters[ AsParameter( param ) ];
					IDataParameter dp;
					// some provider libraries use the actual name (e.g. mysql) and
					// others add prefixes and suffixes (e.g. mssql) 
					if( cmd.Parameters.Contains( param ) )
					{
						dp = (IDataParameter) cmd.Parameters[ param ];
					}
					else
					{
						string paramName = ParameterPrefix + param + ParameterSuffix;
						if( cmd.Parameters.Contains( paramName ) )
						{
							dp = (IDataParameter) cmd.Parameters[ paramName ];
						}
						else
						{
							dp = (IDataParameter) cmd.Parameters[ index++ ];
						}
					}
					Check.VerifyNotNull( dp, Error.Unspecified, "Unable to locate parameter: " + param );
					dp.Value = paramValue;
				}
			}
			return new SqlStatement( SessionBroker, stmtType, cmd, ToString(), type, rowLimit, rowOffset );
		}
예제 #21
0
		/// <summary>
		/// This method assumes that the tableName and identityColumn parameters are passed
		/// in the correct case. 
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details on the
		/// purpose of this method. 
		/// </summary>
		/// <param name="sql">The sql string to which we should append</param>
		/// <param name="om">An <see cref="Gentle.Framework.ObjectMap"/> instance of the object for which to retrieve the identity select</param>
		/// <returns>The modified sql string which also retrieves the identity value</returns>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			return String.Format( "{0}{1} {2}", sql, GetStatementTerminator(),
			                      "select LAST_INSERT_ID()" );
		}
예제 #22
0
		/// <summary>
		/// This method assumes that the tableName and identityColumn parameters are passed
		/// in the correct case. 
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details on the
		/// purpose of this method. 
		/// </summary>
		/// <param name="sql">The sql string to which we should append</param>
		/// <param name="om">An <see cref="Gentle.Framework.ObjectMap"/> instance of the object for which to retrieve the identity select</param>
		/// <returns>The modified sql string which also retrieves the identity value</returns>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			return sql + "; select last_insert_rowid()";
		}
예제 #23
0
		/// <summary>
		/// Construct a new SqlStatement instance of the specified type. The command object to be used
		/// for executing the query and the fully specified sql query string must be specified.  
		/// </summary>
		/// <param name="broker">The PersistenceBroker instance to use for database access.</param>
		/// <param name="stmtType">The type of this statement.</param>
		/// <param name="cmd">The command object to use when executing the query.</param>
		/// <param name="sql">The fully specified sql query string.</param>
		/// <param name="type">The type of object being selected by this query or null if 
		/// not applicable.</param>
		/// <param name="rowLimit">The maximum number of rows to be returned by this query 
		/// or 0 for no limit.</param>
		/// <param name="rowOffset">The number of rows to be skipped by this statement. Note that
		/// for SQL Server this is applied after execution, whereas for other databases it is 
		/// embedded in the SQL string.</param>
		public SqlStatement( PersistenceBroker broker, StatementType stmtType, IDbCommand cmd,
		                     string sql, Type type, int rowLimit, int rowOffset ) : base( broker, type )
		{
			this.cmd = cmd;
			cmd.CommandText = sql;
			statementType = stmtType == StatementType.Unknown ? GetStatementType( sql ) : stmtType;
			map = type != null ? ObjectFactory.GetMap( broker, type ) : null;
			this.rowLimit = rowLimit;
			this.rowOffset = rowOffset;
		}
예제 #24
0
		/// <summary>
		/// TODO FIXME 
		/// This method breaks use of multiple brokers, as it is static and references Broker (and thus DefaultProvider).
		/// </summary>
		internal static object GetParameterValue( object val, ObjectMap map, FieldMap fm, StatementType stmtType )
		{
			Check.VerifyNotNull( map, Error.NullParameter, "map" );
			Check.VerifyNotNull( fm, Error.NullParameter, "fm" );
			object result;
			// make a quick exit with the type name if the column is used for inheritance mapping
			if( map.InheritanceMap != null && fm.ColumnName == map.InheritanceMap.ColumnName )
			{
				return map.Type.AssemblyQualifiedName;
			}
			// null handling
			if( fm.IsNull( val ) )
			{
				// verify that null assignment isn't violating known defintions
				// dont check value types as they are never nullable, and allow null for autogenerated PKs
				if( val == null && ! fm.IsValueType && ! (fm.IsPrimaryKey && fm.IsAutoGenerated) )
				{
					Check.Verify( fm.IsNullable, Error.NullProperty, fm.MemberName, map.Type );
				}
				result = DBNull.Value;
			}
			else
			{
				// clip strings to make sure they fit target column
				if( fm.Type == typeof(string) && val != null &&
				    fm.Size > 0 && ((string) val).Length > fm.Size )
				{
					result = ((string) val).Substring( 0, fm.Size );
				} 
					// clip DateTime values
				else if( fm.Type == typeof(DateTime) )
				{
					// ensure that datetime values are clipped if outside database range
					result = EnsureValidDate( (DateTime) val );
				} 
					// convert enum values to numeric value
				else if( fm.Type.IsEnum )
				{
					// use the integer or string value of the enum
					result = fm.HandleEnumAsString
					         	? Convert.ChangeType( val, typeof(string) )
					         	: Convert.ChangeType( val, Enum.GetUnderlyingType( fm.Type ) );
				} 
					// if column is autogenerated primary key use DBNull if an integer value of 0 is given
				else if( fm.IsAutoGeneratedKeyAndSupportedType && val.Equals( 0 ) && stmtType == StatementType.Insert )
				{
					result = DBNull.Value;
				}
				else if( fm.Type == typeof(byte[]) || fm.Type == typeof(Byte[]) )
				{
					MemoryStream stream = new MemoryStream( (byte[]) val );
					result = stream.ToArray();
				}
				else if( fm.Type == typeof(Guid) && fm.Size == 16 )
				{
					result = TypeConverter.ToBinaryString( (Guid) val );
				}
				else if( fm.Type == typeof(Guid) && Broker.ProviderName.StartsWith( "Sybase" ) )
				{
					// Sybase needs the GUID as a string
					result = val.ToString();
				}
				else // no special handling for other types/values
				{
					result = val;
				}
			}
			return result;
		}
예제 #25
0
		/// <summary>
		/// Please refer to the documentation of <see cref="GentleSqlFactory"/> for details. 
		/// </summary>
		public override string GetIdentitySelect( string sql, ObjectMap om )
		{
			string seqName = (om.IdentityMap.SequenceName != null ? om.IdentityMap.SequenceName : (om.TableName + "_seq").ToUpper());
			return String.Format( "select {0}.currval from dual", seqName );
		}
예제 #26
0
		private static Type GetColumnType( string columnName, ObjectMap map, SqlResult sr )
		{
			Type result = null;
			if( map != null )
			{
				FieldMap fm = map.GetFieldMapFromColumn( columnName );
				if( fm != null )
				{
					result = fm.Type;
				}
			}
			if( result == null && sr.RowsContained > 0 )
			{
				object obj = sr.GetObject( 0, columnName );
				if( obj != null )
				{
					result = obj.GetType();
				}
			}
			return result;
		}
예제 #27
0
		/// <summary>
		/// This method updated the given ObjectMap instance with metadata obtained
		/// from the database.
		/// </summary>
		/// <param name="map">The ObjectMap to update</param>
		public virtual void UpdateObjectMap( ObjectMap map )
		{
			if( level != AnalyzerLevel.None )
			{
				TableMap dbMap = TableMaps[ map.TableName.ToLower() ] as TableMap;
				if( dbMap == null && level == AnalyzerLevel.OnDemand )
				{
					Analyze( map.TableName );
					dbMap = TableMaps[ map.TableName.ToLower() ] as TableMap;
				}
				Check.VerifyNotNull( dbMap, Error.UnknownTable, map.TableName, map.Type );
				// make sure table name is set
				map.Provider = provider;
				// transfer table information
				map.IsView = dbMap.IsView;
				bool isUseData = ! map.IsView;
				isUseData |= map.IsView && HasCapability( ColumnInformation.IsView );
				// transfer column information
				IList processedFields = new ArrayList( map.Fields.Count );
				foreach( FieldMap dbfm in dbMap.Fields )
				{
					try
					{
						FieldMap fm = map.Fields.FindColumn( dbfm.ColumnName );
						if( fm != null )
						{
							// view information
							if( map.IsView )
							{
								if( HasCapability( ColumnInformation.ViewType ) )
								{
									fm.SetDbType( dbfm.DbType );
								}
								if( HasCapability( ColumnInformation.ViewSize ) )
								{
									fm.SetSize( dbfm.Size );
								}
								if( HasCapability( ColumnInformation.ViewIsNullable ) )
								{
									fm.SetIsNullable( dbfm.IsNullable );
								}
								if( HasCapability( ColumnInformation.ViewIsPrimaryKey ) )
								{
									fm.SetIsPrimaryKey( dbfm.IsPrimaryKey );
								}
								if( HasCapability( ColumnInformation.ViewIsAutoGenerated ) )
								{
									fm.SetIsAutoGenerated( dbfm.IsAutoGenerated );
								}
								if( HasCapability( ColumnInformation.ViewIsForeignKey ) && dbfm.IsForeignKey )
								{
									fm.SetForeignKeyTableName( dbfm.ForeignKeyTableName );
									fm.SetForeignKeyColumnName( dbfm.ForeignKeyColumnName );
								}
							}
							else // table information
							{
								if( HasCapability( ColumnInformation.TableType ) )
								{
									fm.SetDbType( dbfm.DbType );
								}
								if( HasCapability( ColumnInformation.TableSize ) )
								{
									fm.SetSize( dbfm.Size );
								}
								if( HasCapability( ColumnInformation.TableIsNullable ) )
								{
									fm.SetIsNullable( dbfm.IsNullable );
								}
								if( HasCapability( ColumnInformation.TableIsPrimaryKey ) )
								{
									fm.SetIsPrimaryKey( dbfm.IsPrimaryKey );
								}
								if( HasCapability( ColumnInformation.TableIsAutoGenerated ) )
								{
									fm.SetIsAutoGenerated( dbfm.IsAutoGenerated );
								}
								if( HasCapability( ColumnInformation.TableIsForeignKey ) && dbfm.IsForeignKey )
								{
									fm.SetForeignKeyTableName( dbfm.ForeignKeyTableName );
									fm.SetForeignKeyColumnName( dbfm.ForeignKeyColumnName );
								}
							}
							// remember which fields have been processed (for error reporting later)
							processedFields.Add( fm );
						}
					}
					catch
					{
						// ignore the error but log a warning
						Check.LogWarning( LogCategories.Metadata,
						                  "Type {0} contains no mapping for column {1} in table {2}.",
						                  map.Type.Name, dbfm.ColumnName, map.TableName );
					}
				}
				// verify that all defined fields had an existing column in the target table
				if( isUseData && processedFields.Count < map.Fields.Count )
				{
					// construct informative error message
					StringBuilder sb = new StringBuilder();
					bool single = processedFields.Count == map.Fields.Count - 1;
					sb.AppendFormat( "The column{0} ", single ? "" : "s" );
					bool delimit = false;
					foreach( FieldMap fm in map.Fields )
					{
						if( ! processedFields.Contains( fm ) )
						{
							sb.AppendFormat( "{0}{1}", delimit ? ", " : "", fm.ColumnName );
							delimit = true;
						}
					}
					sb.AppendFormat( " in table {0} do{1} not exist.", map.TableName, single ? "es" : "" );
					// raise an exception
					Check.Fail( Error.DeveloperError, sb.ToString() );
				}
			}
		}
예제 #28
0
        /// <summary>
        /// Construct multiple objects of a given type from the data contained in the given SqlResult
        /// object. Refer to the Construct method of the <see cref="ObjectMap"/> class for details.
        /// </summary>
        /// <param name="type">The type of object to construct</param>
        /// <param name="sr">The SqlResult instance holding the data</param>
        /// <param name="result">An optional existing container in which to store the created objects. If
        /// this parameter is null a new IList instance will be created.</param>
        /// <returns>An IList holding the created objects</returns>
        /// <exception cref="GentleException"> will be raised if no object could be created</exception>
        public static IList GetCollection(Type type, SqlResult sr, IList result)
        {
            if (result == null)
            {
                result = MakeGenericList(type);
            }
            ObjectMap objectMap = GetMap(sr.SessionBroker, type);
            // check whether to store query result information
            bool isCache = GentleSettings.CacheObjects && GentleSettings.SkipQueryExecution &&
                           objectMap.CacheStrategy != CacheStrategy.Never;
            IList cache = isCache ? new ArrayList() : null;

            // remember keys of cached objects to permit SQE
            // process result set
            if (sr.RowsContained > 0)
            {
                ObjectMap actualMap           = objectMap;
                int       columnComboHashCode = 0;
                // cache constructor info for dynamic type construction
                Hashtable typeHash = null;
                Hashtable typeMaps = null;
                if (objectMap.InheritanceMap != null)
                {
                    typeHash = new Hashtable();
                    typeMaps = new Hashtable();
                }
                else                 // precompute fixed hash
                {
                    columnComboHashCode = objectMap.DetermineConstructor(sr.ColumnNames, (object[])sr.Rows[0]);
                }
                // process result set
                for (int i = 0; i < sr.Rows.Count; i++)
                {
                    object[] row = (object[])sr.Rows[i];
                    // dynamic object construction handling
                    if (typeHash != null)
                    {
                        string assemblyQualifiedName = sr.GetString(i, objectMap.InheritanceMap.ColumnName);
                        if (typeHash.ContainsKey(assemblyQualifiedName))
                        {
                            columnComboHashCode = (int)typeHash[assemblyQualifiedName];
                            actualMap           = (ObjectMap)typeMaps[assemblyQualifiedName];
                        }
                        else
                        {
                            Type rowType = LoadType(assemblyQualifiedName);
                            actualMap                       = GetMap(sr.SessionBroker, rowType);
                            columnComboHashCode             = actualMap.DetermineConstructor(sr.ColumnNames, (object[])sr.Rows[0]);
                            typeMaps[assemblyQualifiedName] = actualMap;
                            typeHash[assemblyQualifiedName] = columnComboHashCode;
                        }
                    }
                    // skip non-derived classes for dynamic types
                    if (actualMap.Type == objectMap.Type || actualMap.Type.IsSubclassOf(objectMap.Type))
                    {
                        object obj = actualMap.Construct(columnComboHashCode, row, sr.SessionBroker);
                        if (obj is IEntity)
                        {
                            (obj as IEntity).IsPersisted = true;
                        }
                        result.Add(obj);
                        // cache result if necessary
                        if (isCache)
                        {
                            cache.Add(actualMap.GetInstanceHashKey(obj));
                        }
                    }
                }
            }
            if (isCache)
            {
                CacheManager.Insert(sr.Statement.CacheKey, cache);
            }
            return(result);
        }