Пример #1
0
 internal Key ResolveForeignKeyReferences(Type type, Key key)
 {
     // determine whether we need to translate names
     if (key.SourceType != null && key.SourceType != type)
     {
         // translate column names in key to foreign key name in table used by type
         Key       fkKey = new Key(type, false);
         ObjectMap map   = ObjectFactory.GetMap(this, key.SourceType);
         ObjectMap fkMap = ObjectFactory.GetMap(this, type);
         foreach (string name in key.Keys)
         {
             string   fieldName = key.isPropertyKeys ? name : map.GetPropertyName(name);
             FieldMap fkfm      = fkMap.GetForeignKeyFieldMap(map.Type, fieldName);
             fkKey[fkfm.ColumnName] = key[name];
         }
         key = fkKey;
     }
     return(key);
 }
Пример #2
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);
        }
Пример #3
0
        /// <summary>
        /// <p>Update the statement parameter values using the values from the key.</p>
        /// <p>Warning! This will erase all parameter values not in the key, so if you
        /// need to set additional parameters be sure to call this method before
        /// any calls to SetParameter.</p>
        /// </summary>
        /// <param name="key">The key instance containing the parameter values.</param>
        /// <param name="isUpdateAll">If true all statement parameters will be updated. If the
        /// key has no value a null value will be assigned.</param>
        public void SetParameters(Key key, bool isUpdateAll)
        {
            Check.VerifyNotNull(key, Error.NullParameter, "key");
            GentleSqlFactory sf = broker.GetSqlFactory();

            foreach (IDataParameter param in cmd.Parameters)
            {
                // strip leading @ character if present
                string prefix    = sf.GetParameterPrefix();
                string suffix    = sf.GetParameterSuffix();
                string paramName = param.ParameterName;
                if (paramName.StartsWith(prefix))
                {
                    paramName = paramName.Substring(prefix.Length, paramName.Length - prefix.Length);
                }
                //if needed, strip out the suffix from the paramName/column name
                if (suffix != "" && paramName.EndsWith(suffix))
                {
                    paramName = paramName.Substring(0, paramName.Length - suffix.Length);
                }
                FieldMap fm = map.GetFieldMapFromColumn(paramName);
                // handle special case where parameter is concurrency control column
                if (fm == null && map.ConcurrencyMap != null && paramName.StartsWith("New") &&
                    (paramName.Substring(3, paramName.Length - 3) == map.ConcurrencyMap.ColumnName))
                {
                    fm = map.ConcurrencyMap;
                }
                // if key contains property names translate parameter name into property name
                string index = key.isPropertyKeys ? fm.MemberName : paramName;
                // check if we should set parameter value
                if (key.ContainsKey(index) || isUpdateAll)
                {
                    Check.VerifyNotNull(fm, Error.Unspecified, "Could not find a value for the parameter named {0}", index);
                    SetParameter(param, key.ContainsKey(index) ? key[index] : null, fm);
                }
            }
        }
Пример #4
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());
         }
     }
 }
Пример #5
0
		/// <summary>
		/// Please refer to the <see cref="GentleAnalyzer"/> class and the <see cref="IDatabaseAnalyzer"/> 
		/// interface it implements a description of this method.
		/// </summary>
		public override void Analyze( string tableName )
		{
			try
			{
				bool isSingleRun = tableName != null;
				string selectSingle = isSingleRun ? String.Format( SELECT_SINGLE, tableName ) : String.Empty;

				// Check Oracle version and select appropriate SQL-Syntax
				SqlResult sr = broker.Execute( ORA_VERSION_SELECT );
				//				string ver = sr.GetString( 0, "Version" ).Substring( 0, 1 );
				//				int version = Convert.ToInt32( sr.GetString( 0, "Version" ).Substring( 0, 1 ) );

				string ver = sr.GetString( 0, "Version" );

				int indexOfDot = ver.IndexOf( "." );
				if( indexOfDot < 0 )
				{
					throw new GentleException( Error.DeveloperError, "Unable to determine Oracle database version." );
				}

				int version = Convert.ToInt32( ver.Substring( 0, indexOfDot ) );

				string select;
				string selectReferences;
				if( version < 9 )
				{
					// If Oracle version == '8.1.6' use no-views selectReferences
					if( ver.Substring( 0, 5 ).CompareTo( "8.1.6" ) == 0 )
					{
						selectReferences = ORA816_SELECT_REFERENCES;
					}
					else
					{
						selectReferences = ORA8_SELECT_REFERENCES;
					}
					select = ORA8_SELECT + selectSingle + ORDER_BY;
				}
				else
				{
					select = ORA9_SELECT + selectSingle + ORDER_BY;
					selectReferences = ORA9_SELECT_REFERENCES;
				}

				sr = broker.Execute( select );
				// process result set using columns:
				// TableName, ColumnName, Type, Size, IsNullable, DefaultValue, 
				// ConstraintName, ConstraintReference, ConstraintType, UpdateRule, DeleteRule
				for( int i = 0; i < sr.Rows.Count; i++ )
				{
					try
					{
						string dbTableName = sr.GetString( i, "TableName" );
						if( ! isSingleRun || tableName.ToLower().Equals( dbTableName.ToLower() ) )
						{
							// get or create TableMap for table 
							TableMap map = GetTableMap( dbTableName );
							if( map == null )
							{
								map = new TableMap( provider, dbTableName );
								maps[ dbTableName.ToLower() ] = map;
							}
							// get or create FieldMap for column
							string columnName = sr.GetString( i, "ColumnName" );
							FieldMap fm = map.GetFieldMapFromColumn( columnName );
							if( fm == null )
							{
								fm = new FieldMap( map, columnName );
								map.Fields.Add( fm );
							}
							// get basic column information
							fm.SetDbType( sr.GetString( i, "Type" ), false );
							fm.SetIsNullable( GetBoolean( sr.GetString( i, "IsNullable" ) ) );

							if( sr[ i, "Size" ] != null )
							{
								if( fm.DbType == (long) OracleType.Clob )
								{
									//Max 4GB
									//Preferred size 4294967296
									fm.SetSize( int.MaxValue );
								}
								else
								{
									fm.SetSize( sr.GetInt( i, "Size" ) );
								}
							}

							// get column constraint infomation
							if( sr[ i, "ConstraintName" ] != null )
							{
								string typ = sr.GetString( i, "ConstraintType" );
								if( typ.ToLower().Equals( "p" ) )
								{
									fm.SetIsPrimaryKey( true );
								}
								else if( typ.ToLower().Equals( "r" ) )
								{
									string conref = sr.GetString( i, "ConstraintReference" );
									SqlResult res = broker.Execute( String.Format( selectReferences, conref ) );
									fm.SetForeignKeyTableName( res.GetString( 0, "ChildTable" ) );
									fm.SetForeignKeyColumnName( res.GetString( 0, "ChildColumn" ) );
								}
							}
						}
					}
					catch( GentleException fe )
					{
						// ignore errors caused by tables found in db but for which no map exists
						// TODO this should be a config option
						if( fe.Error != Error.NoObjectMapForTable )
						{
							throw;
						}
					}
				}
			}
			catch( Exception e )
			{
				Check.LogInfo( LogCategories.General, "Using provider {0} and connectionString {1}.",
				               provider.Name, provider.ConnectionString );
				Check.Fail( e, Error.Unspecified, "An error occurred while analyzing the database schema." );
			}
		}
Пример #6
0
		/// <summary>
		/// Please refer to the <see cref="GentleAnalyzer"/> class and the <see cref="IDatabaseAnalyzer"/> 
		/// interface it implements a description of this method.
		/// </summary>
		public override void Analyze( string tableName )
		{
			GentleSqlFactory sf = provider.GetSqlFactory();
			try
			{
				bool isSingleRun = tableName != null;
				// don't quote reserved words here (table name is just a string parameter)
				string sql = isSingleRun ? select + String.Format( selectSingle, tableName ) : select;
				SqlResult sr = broker.Execute( sql, null, null );
				// process result set using columns:
				// TableName, ColumnName, Type, Size, IsNullable, DefaultValue, 
				// ConstraintName, ConstraintReference, ConstraintType, 
				// UpdateRule, DeleteRule, TableType
				for( int i = 0; i < sr.Rows.Count; i++ )
				{
					try
					{
						string dbTableName = sr.GetString( i, "tablename" );
						if( ! isSingleRun || tableName.ToLower().Equals( dbTableName.ToLower() ) )
						{
							TableMap map = GetTableMap( dbTableName );
							if( map == null )
							{
								map = new TableMap( provider, dbTableName );
								maps[ dbTableName.ToLower() ] = map;
							}
							map.IsView = sr.GetString( i, "TableType" ) == "VIEW";
							// get column information for this table
							string columnName = sr.GetString( i, "ColumnName" );
							FieldMap fm = map.GetFieldMapFromColumn( columnName );
							if( fm == null )
							{
								fm = new FieldMap( map, columnName );
								map.Fields.Add( fm );
							}
							// get basic column information
							fm.SetDbType( sr.GetString( i, "Type" ), false ); // sql server is always false
							fm.SetIsNullable( GetBoolean( sr.GetString( i, "IsNullable" ) ) );
							fm.SetIsAutoGenerated( sr.GetString( i, "DefaultValue" ).Length > 0 ? true : false );
							if( sr[ i, "Size" ] != null && fm.DbType != (long) SqlDbType.Text )
							{
								fm.SetSize( sr.GetInt( i, "Size" ) );
							}
							// get column constraint infomation
							if( sr[ i, "ConstraintName" ] != null )
							{
								string type = sr.GetString( i, "ConstraintType" );
								if( type.ToLower().Equals( "primary key" ) )
								{
									fm.SetIsPrimaryKey( true );
								}
								else if( type.ToLower().Equals( "foreign key" ) )
								{
									string conref = sr.GetString( i, "ConstraintReference" );
									if( conref.StartsWith( "IDX" ) )
									{
										string fkRef = sr.GetString( i, "ConstraintName" );
										if( fkRef != null && fkRef.StartsWith( "FK" ) )
										{
											conref = fkRef;
										}
									}
									SqlResult res = broker.Execute( String.Format( selectReferences, conref ), null, null );
									if( res.ErrorCode == 0 && res.RowsContained == 1 )
									{
										fm.SetForeignKeyTableName( res.GetString( 0, "TableName" ) );
										fm.SetForeignKeyColumnName( res.GetString( 0, "ColumnName" ) );
									}
									else
									{
										if( res.RowsContained == 0 )
										{
											// see GOPF-155 for additional information
											Check.LogWarning( LogCategories.Metadata,
											                  "Unable to obtain foreign key information for column {0} of table {1}.",
											                  fm.ColumnName, map.TableName );
										}
										else
										{
											Check.LogWarning( LogCategories.Metadata, "Gentle 1.x does not support composite foreign keys." );
										}
									}
								}
							}
							if( map.IsView )
							{
								// TODO 
								// process backing table members and infer PK/identity info
								// requires that tables be processed before views!
								// 
								//string sv = String.Format( selectViewDependencies, map.TableName );
								//SqlResult res = broker.Execute( sv );
							}
						}
					}
					catch( GentleException fe )
					{
						// ignore errors caused by tables found in db but for which no map exists
						// TODO this should be a config option
						if( fe.Error != Error.NoObjectMapForTable )
						{
							throw;
						}
					}
				}
			}
			catch( Exception e )
			{
				Check.LogInfo( LogCategories.General, "Using provider {0} and connectionString {1}.",
				               provider.Name, provider.ConnectionString );
				Check.Fail( e, Error.Unspecified, "An error occurred while analyzing the database schema." );
			}
		}
Пример #7
0
		private void GetColumnData( TableMap map )
		{
			string sql = String.Format( selectColumns, map.TableId );
			SqlResult sr = broker.Execute( sql );
			for( int i = 0; i < sr.Rows.Count; i++ )
			{
				string column = sr.GetString( i, "column_name" );
				FieldMap fm = map.GetFieldMapFromColumn( column );
				if( fm == null )
				{
					fm = new FieldMap( map, column );
					map.Fields.Add( fm );
				}

				bool isNullable = sr.GetString( i, "nulls" ).Equals( "Y" );
				bool isAutoGenerated = sr.GetString( i, "default" ).ToLower() == "autoincrement";
				fm.ColumnId = sr.GetInt( i, "column_id" );
				fm.SetDbType( sr.GetString( i, "domain_name" ), false );
				fm.SetIsNullable( isNullable );
				fm.SetIsAutoGenerated( isAutoGenerated );
				fm.SetSize( sr.GetInt( i, "width" ) );
			}
		}
        private void InitConstructorMap(object[] row)
        {
            columnOrderMap = new int[columnInfo.Names.Length];
            ParameterInfo[] pis = constructorInfo.GetParameters();
            constructorParameterCount = pis.Length;
            // use a counter to determine whether we have a column for every parameter
            int  noColumnForParameter = constructorParameterCount;
            bool isPerfectColumnOrder = true;

            // process columns
            for (int i = 0; i < columnInfo.Names.Length; i++)
            {
                FieldMap fm         = columnInfo.Fields[i];
                string   columnName = fm != null?fm.ColumnName.ToLower() : columnInfo.Names[i].ToLower();

                string memberName = fm != null?fm.MemberName.ToLower() : null;

                bool foundParam = false;
                for (int j = 0; j < pis.Length; j++)
                {
                    string parameterName = pis[j].Name.ToLower();
                    if (parameterName == columnName || (fm != null && parameterName == memberName))
                    {
                        noColumnForParameter--;
                        foundParam = true;
                        columnConstructorUsageCount += 1;
                        columnConstructorMask[i]     = true;
                        columnOrderMap[i]            = j;
                        isPerfectColumnOrder        &= i == j;
                        // also flag primary keys
                        if (fm != null && fm.IsPrimaryKey)
                        {
                            columnPrimaryKeyMask[i] = true;
                        }
                        break;
                    }
                }
                if (!foundParam)
                {
                    if (fm != null)
                    {
                        // column not included in constructor but member field is present
                        columnReflectionMask[i] = true;
                        cost += 1000;
                        // also flag primary keys
                        if (fm.IsPrimaryKey)
                        {
                            columnPrimaryKeyMask[i] = true;
                        }
                    }
                    else
                    {
                        // unused column - not in constructor or as member field
                        columnUnusedMask[i] = true;
                        // log a warning
                        Check.LogWarning(LogCategories.Metadata,
                                         "The column {0} does not match any member or constructor parameter " +
                                         "of type {1}. It will therefore not be used during object construction.",
                                         columnInfo.Names[i], objectMap.Type);
                    }
                }
                // determine if type conversion is required for column
                if (fm != null)
                {
                    // type conversion required for nullable columns mapping to not-nullable system type
                    // or when result set type is different from member/parameter type
                    if (fm.NullValue != null ||
                        (row[i] != null && fm.Type != row[i].GetType() && !fm.IsGenericNullableType))
                    {
                        columnTypeConvertMask[i] = true;
                        cost += 1;
                    }
                }
            }
            // score 100 if parameter and column count differ
            cost += columnConstructorUsageCount == pis.Length ? 0 : 100;
            // score 300 if column order does not match parameter order
            cost += isPerfectColumnOrder ? 0 : 300;
            // score 600 if type conversion for any column is required
            cost += AllUnset(columnTypeConvertMask) ? 0 : 600;
            // determine whether we have a perfect match (can use direct constructor invocation)
            isPerfectMatch  = isPerfectColumnOrder && columnConstructorUsageCount == pis.Length;
            isPerfectMatch &= AllUnset(columnUnusedMask) && AllUnset(columnTypeConvertMask);
            isPerfectMatch &= cost == 0;
            // isValid tells whether this CM can be used with the given columns
            isValid = noColumnForParameter == 0;
        }
Пример #9
0
        /// <summary>
        /// Obtain the column name corresponding to a given property name.
        /// </summary>
        /// <param name="propertyName">The name of the property</param>
        /// <returns>The name of the column</returns>
        public string GetColumnName(string propertyName)
        {
            FieldMap fm = Fields.FindProperty(propertyName);

            return(fm != null ? fm.ColumnName : null);
        }
Пример #10
0
        /// <summary>
        /// Internal helper method used for standard CRUD operations on known types.
        /// </summary>
        /// <param name="obj">The object instance being operated on</param>
        /// <param name="st">The statement type</param>
        /// <param name="conn">An existing database connection to reuse. This is useful
        /// when you need to execute statements in the same session as a previous statement.</param>
        /// <param name="tr">The database transaction for when participating in transactions.</param>
        /// <returns>The result of the operation</returns>
        internal SqlResult Execute(object obj, StatementType st, IDbConnection conn, IDbTransaction tr)
        {
            ObjectMap map = ObjectFactory.GetMap(this, obj);

            // perform validations first
            if (StatementType.Insert == st || StatementType.Update == st)
            {
                ValidationBroker.Validate(obj);
            }

            if (map.IsSoftDelete && st == StatementType.Delete)
            {
                st = StatementType.SoftDelete;
            }
            SqlStatement stmt = GetStatement(obj, st);

            stmt.SetParameters(obj, true);
            // connections are supplied from outside when in a transaction or executing batch queries
            conn = tr != null ? tr.Connection : conn ?? stmt.SessionBroker.Provider.GetConnection();
            SqlResult sr = stmt.Execute(conn, tr);

            // throw an error if execution failed
            Check.Verify(sr.ErrorCode == 0, Error.StatementError, sr.Error, stmt.Sql);
            // check that statement affected a row
            if (st == StatementType.Insert || st == StatementType.Update ||
                st == StatementType.Delete || st == StatementType.SoftDelete)
            {
                Check.Verify(sr.RowsAffected >= 1, Error.UnexpectedRowCount, sr.RowsAffected, "1+");
            }
            // update identity values for inserts
            if (st == StatementType.Insert)
            {
                if (sr.LastRowId != 0 && map.IdentityMap != null)
                {
                    map.SetIdentity(obj, sr.LastRowId);
                }
                if (obj is IEntity)
                {
                    (obj as IEntity).IsPersisted = true;
                }
                // this is not really necessary but nice for error checking (also used in test cases)
                if (map.InheritanceMap != null)
                {
                    map.InheritanceMap.SetValue(obj, obj.GetType().AssemblyQualifiedName);
                }
            }
            // update/invalidate the cache
            if (GentleSettings.CacheObjects && map.CacheStrategy != CacheStrategy.Never)
            {
                if (st == StatementType.Insert)
                {
                    // insert new object into cache
                    CacheManager.Insert(map.GetInstanceHashKey(obj), obj, map.CacheStrategy);
                    // invalidate query results for select statements for this type, reducing the
                    // effectiveness of the cache (but ensuring correct results)
                    if (GentleSettings.CacheStatements)
                    {
                        CacheManager.ClearQueryResultsByType(map.Type);
                    }
                }
                else if (st == StatementType.Delete || st == StatementType.SoftDelete)
                {
                    // remove invalidated object from the cache
                    CacheManager.Remove(obj);
                    // invalidate query results for select statements for this type, reducing the
                    // effectiveness of the cache (but ensuring correct results)
                    if (GentleSettings.CacheStatements)
                    {
                        CacheManager.ClearQueryResultsByType(map.Type);
                    }
                }
            }
            // update the in-memory version/revision counter for objects under concurrency control
            if (st == StatementType.Update && GentleSettings.ConcurrencyControl)
            {
                if (map.ConcurrencyMap != null)
                {
                    FieldMap fm      = map.ConcurrencyMap;
                    long     version = Convert.ToInt64(fm.GetValue(obj));
                    // handle wrap-around of the version counter
                    if ((fm.Type.Equals(typeof(int)) && version == int.MaxValue) ||
                        (fm.Type.Equals(typeof(long)) && version == long.MaxValue))
                    {
                        version = 1;
                    }
                    else
                    {
                        version += 1;
                    }
                    map.ConcurrencyMap.SetValue(obj, version);
                }
            }
            // update object with database-created values if UpdateAfterWrite is set to true
            if (map.IsUpdateAfterWrite && (st == StatementType.Insert || st == StatementType.Update))
            {
                if (tr != null)
                {
                    Refresh(obj, tr);
                }
                else
                {
                    Refresh(obj);
                }
            }
            return(sr);
        }
Пример #11
0
        /// <summary>
        /// Obtain the system type of the given property.
        /// </summary>
        /// <param name="propertyName">The name of the property</param>
        /// <returns>The system type of the property</returns>
        public Type GetPropertyType(string propertyName)
        {
            FieldMap fm = Fields.FindProperty(propertyName);

            return(fm != null ? fm.Type : null);
        }
Пример #12
0
		/// <summary>
		/// This method is for adding set membership constraints using either Operator.In or
		/// Operator.NotIn. If an invalid operator is used this method will throw an exception.
		/// </summary>
		/// <param name="op">The operator used for this constraint.</param>
		/// <param name="fieldMap">The FieldMap instance for the field to constrain. The framework 
		/// assumes property names but
		/// also checks column names if no property could be found.</param>
		/// <param name="data">The set of data to constrain on.</param>
		/// <param name="constraintMap">If the constraint data set holds objects this is the property
		/// name to gather from all objects. If the data set is an SqlResult this is the column name
		/// to use from all rows. String-type fields are quoted, all other types are not. This method
		/// performs no additional type checking and is likely to fail (when the statement is executed)
		/// for esoteric types such as decimals or dates.</param>
		public void AddConstraint( Operator op, FieldMap fieldMap, ICollection data, FieldMap constraintMap )
		{
			Check.VerifyNotNull( fieldMap, Error.NullParameter, "field" );
			Check.VerifyNotNull( data, Error.NullParameter, "data" );
			Check.IsTrue( op == Operator.In || op == Operator.NotIn, Error.DeveloperError,
			              "This AddConstraint method must be used only with the In and NotIn operators." );
			// TODO make this a config option (e.g. "strict" behavior)
			// Check.Verify( data.Count > 0, Error.EmptyListParameter, "data" );
			if( data.Count > 0 )
			{
				// convert supplied collection into comma-delimited list of values 
				string[] list = new string[data.Count];
				int count = 0;
				foreach( object obj in data )
				{
					if( constraintMap == null )
					{
						list[ count++ ] = Convert.ToString( obj );
					}
					else
					{
						list[ count++ ] = Convert.ToString( constraintMap.GetValue( obj ) );
					}
				}
				// determine whether field type needs quoting
				bool needsQuoting = fieldMap.Type.Equals( typeof(string) );
				needsQuoting |= fieldMap.Type.Equals( typeof(DateTime) );
				// quote GUIDs (only when they are not in binary form)
				needsQuoting |= fieldMap.Type.Equals( typeof(Guid) ) && (fieldMap.Size == 0 || fieldMap.Size > 16);
				// add the constraint
				AddConstraint( String.Format( "{0} {1} {2} {3}", fieldMap.QuotedColumnName,
				                              AsOperatorBegin( op, false ),
				                              AsCommaList( list, needsQuoting ),
				                              AsOperatorEnd( op ) ) );
			}
		}
Пример #13
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;
		}
Пример #14
0
		internal void AddParameter( FieldMap fm )
		{
			AddParameter( null, fm );
		}
Пример #15
0
		/// <summary>
		/// Add a parameter to the current statement.
		/// </summary>
		/// <param name="name">The parameter name to use if not the column name defined in the FieldMap</param>
		/// <param name="fm">The FieldMap describing this parameter</param>
		internal void AddParameter( string name, FieldMap fm )
		{
			//string paramName = sf.GetParameterPrefix() + (name != null ? name : fm.ColumnName) + sf.GetParameterSuffix();
			string paramName = name != null ? name : fm.ColumnName;
			string paramKey = sf.GetParameterCollectionKey( paramName );
			// only add parameters once
			// Uwe Kitzmann: data providers with positional parameters may need more than one occurence of the same parameter
			// Uwe Kitzmann: for example "update mytable set field1 = ?, field2 = ? where field1 = ? and field2 = ?"
			if( ! cmd.Parameters.Contains( paramKey ) || ! sf.HasCapability( Capability.NamedParameters ) )
			{
				if( fm.HasDbType )
				{
					// all insert/update columns must use this method
					sf.AddParameter( cmd, paramKey, fm.DbType );
				}
				else
				{
					sf.AddParameter( cmd, paramKey, fm.Type );
				}
				// also remember the order in which we add parameters (using the original name)
				parameterOrder.Add( paramName );
			}
		}
Пример #16
0
        /// <summary>
        /// Obtain the system type of a given column name.
        /// </summary>
        /// <param name="columnName">The name of the column</param>
        /// <returns>The system type of the corresponding property</returns>
        public Type GetColumnType(string columnName)
        {
            FieldMap fm = fields.FindColumn(columnName);

            return(fm != null ? fm.Type : null);
        }
Пример #17
0
 protected virtual void InitList(Type viaType, params Type[] relationTypes)
 {
     if (listType == GentleListType.StandAlone)
     {
         broker.RetrieveList(containedMap.Type, this);
     }
     else if (listType == GentleListType.OneToMany)
     {
         // no relation objects for 1:n relationships
         viaInstances = null;
         mappings     = containedMap.GetForeignKeyMappings(parentMap, true);
         if (mappings.Count == 0)
         {
             mappings = viaMap.GetForeignKeyMappings(parentMap, false);
         }
         Check.Verify(mappings.Count > 0, Error.DeveloperError,
                      "The type {0} does not contain a foreign key reference to type {1}.",
                      parentMap.Type, containedMap.Type);
         Check.Verify(mappings.Count == 1, Error.NotImplemented,
                      "GentleList for 1:n relations can not be used with composite keys.");
         // populate self with any existing entries matching the current parent
         Key key = new Key(parentMap.Type, true);
         IDictionaryEnumerator iterator = mappings.GetEnumerator();
         while (iterator.MoveNext())
         {
             // construct a key to read the data; first obtain the referenced value from
             // the parent object (this is the constraint value used in the select)
             FieldMap fm = iterator.Value as FieldMap;
             object   referencedValue = fm.GetValue(parent);
             // if class references self make sure to pick the outgoing column
             if (containedMap.Type == parentMap.Type && !fm.IsForeignKey)
             {
                 fm = iterator.Key as FieldMap;
             }
             key[fm.MemberName] = referencedValue;
         }
         broker.RetrieveList(containedMap.Type, key, this);
     }
     else if (listType == GentleListType.ManyToMany)
     {
         // create relation for n:m management
         Type[] relatedTypes = Merge(containedMap.Type, relationTypes);
         viaInstances = new GentleRelation(broker, viaType, parent, relatedTypes);
         // populate the list with any existing entries matching the current relation entries
         ObjectMap  viaMap = ObjectFactory.GetMap(broker, viaType);
         SqlBuilder sb     = new SqlBuilder(broker, StatementType.Select, containedMap.Type);
         // assume the relation object is the child, i.e. refers to the contained type
         mappings = viaMap.GetForeignKeyMappings(containedMap, true);
         if (mappings.Count == 0)
         {
             mappings = viaMap.GetForeignKeyMappings(containedMap, false);
         }
         Check.Verify(mappings.Count > 0, Error.DeveloperError,
                      "The type {0} does not contain a foreign key reference to type {1}.",
                      viaMap.Type, containedMap.Type);
         Check.Verify(mappings.Count == 1, Error.NotImplemented,
                      "GentleList for n:m relations can not be used with composite keys.");
         // verify that references point to unique instance
         //Check.Verify( mappings.Count == parentMap.PrimaryKeyCount, Error.DeveloperError,
         //	"The number of fields ({0}) referencing {1} from {2} must equal the primary key count ({3}).",
         //	mappings.Count, parentMap.Type, containedMap.Type, parentMap.PrimaryKeyCount );
         if (viaInstances.Count > 0)
         {
             foreach (FieldMap remote in mappings.Keys)
             {
                 FieldMap local = (FieldMap)mappings[remote];
                 // viaMap.GetForeignKeyFieldMap( containedMap.Type, local.PropertyName );
                 sb.AddConstraint(Operator.In, local.MemberName, viaInstances, remote.MemberName);
             }
             ObjectFactory.GetCollection(containedMap.Type, sb.GetStatement(true).Execute(), this);
         }
     }
 }
Пример #18
0
		public override void Analyze( string tableName )
		{
			GentleSqlFactory sf = provider.GetSqlFactory();
			try
			{
				bool isSingleRun = tableName != null;
				// Create foreign key statement
				SqlStatement fk = broker.GetStatement( StatementType.Select, selectReferences );
				sf.AddParameter( fk.Command, "TableName", (long) FbDbType.VarChar );
				sf.AddParameter( fk.Command, "ColumnName", (long) FbDbType.VarChar );
				// Get tables information
				SqlResult sr = broker.Execute( select );
				// process result set
				for( int i = 0; i < sr.Rows.Count; i++ )
				{
					try
					{
						string dbTableName = sr.GetString( i, "TableName" ).Trim();

						if( ! isSingleRun || tableName.ToLower().Equals( dbTableName.ToLower() ) )
						{
							TableMap map = GetTableMap( dbTableName );
							if( map == null )
							{
								map = new TableMap( provider, dbTableName );
								maps[ dbTableName.ToLower() ] = map;
							}

							// get column information for this table
							string columnName = sr.GetString( i, "ColumnName" ).Trim();
							FieldMap fm = map.GetFieldMapFromColumn( columnName );
							if( fm == null )
							{
								fm = new FieldMap( map, columnName );
								map.Fields.Add( fm );
							}
							FbDbType type = GetFbDbType(
								sr.GetInt( i, "ColumnDataType" ),
								sr[ i, "ColumnSubType" ] != null ? sr.GetInt( i, "ColumnSubType" ) : 0,
								sr[ i, "ColumnScale" ] != null ? sr.GetInt( i, "ColumnScale" ) : 0 );
							fm.SetDbType( (long) type );
							if( sr[ i, "NullFlag" ] == null )
							{
								fm.SetIsNullable( true );
							}
							else
							{
								fm.SetIsNullable( false );
							}
							if( sr[ i, "ColumnSize" ] != null )
							{
								switch( type )
								{
									case FbDbType.Binary:
									case FbDbType.Text:
										fm.SetSize( Int32.MaxValue );
										break;
									default:
										fm.SetSize( sr.GetInt( i, "ColumnSize" ) );
										break;
								}
							}
							if( sr.GetInt( i, "PrimaryKey" ) > 0 )
							{
								fm.SetIsPrimaryKey( true );
							}
							if( sr.GetInt( i, "ForeignKey" ) > 0 )
							{
								fk.SetParameter( "TableName", map.TableName.ToUpper() );
								fk.SetParameter( "ColumnName", columnName.ToUpper() );

								SqlResult res = fk.Execute();
								fm.SetForeignKeyTableName( res.GetString( 0, "FKTableName" ).Trim() );
								fm.SetForeignKeyColumnName( res.GetString( 0, "FKColumnName" ).Trim() );
							}
						}
					}
					catch( GentleException fe )
					{
						// ignore errors caused by tables found in db but for which no map exists
						// TODO this should be a config option
						if( fe.Error != Error.NoObjectMapForTable )
						{
							throw fe;
						}
					}
				}
			}
			catch( Exception e )
			{
				Check.Fail( e, Error.Unspecified, "An error occurred while analyzing the database schema." );
			}
		}
Пример #19
0
		private void SetParameter( IDataParameter param, object val, FieldMap fm )
		{
			Check.Verify( param.Direction == ParameterDirection.Input ||
			              param.Direction == ParameterDirection.InputOutput, "Cannot set value of output parameters!" );
			// do additional checking for known types
			if( map != null && fm != null )
			{
				param.Value = GetParameterValue( val, map, fm, statementType );
			}
			else // unknown type - no clipping or fancy checks, just do it
			{
				param.Value = val ?? DBNull.Value;
			}
		}
Пример #20
0
        /// <summary>
        /// Obtain the property name of a given column name.
        /// </summary>
        /// <param name="columnName">The name of the column</param>
        /// <returns>The name of the property</returns>
        public string GetPropertyName(string columnName)
        {
            FieldMap fm = Fields.FindColumn(columnName);

            return(fm != null ? fm.MemberName : null);
        }
Пример #21
0
		private object ConvertType( FieldMap fm, object val )
		{
			Check.VerifyNotNull( fm, Error.NullParameter, "fm" );
			// convert DBNull to system null
			if( val != null && val.Equals( DBNull.Value ) )
			{
				val = null;
			}
			// perform null handling (NullValue translation)
			if( val == null && ! fm.IsNullAssignable )
			{
				Check.Verify( fm.NullValue != null, Error.NullWithNoNullValue, fm.ColumnName, fm.Type );
				return fm.NullValue;
			}
			else
			{
				if( val != null )
				{
					Type type = val.GetType();
					// trim strings.. otherwise char columns are as wide as their size
					if( fm.Type == typeof(string) || fm.Type == typeof(Guid) )
					{
						if( fm.Type == typeof(Guid) )
						{
							if( fm.Size == 16 ) // binary compressed version
							{
								val = Common.TypeConverter.ToGuid( (string) val );
							}
							else
							{
								val = new Guid( val.ToString() );
							}
						}
						else
						{
							string strval = (string) val;
							// size is 0 for variable width columns
							// assume we should trim all fixed-width columns
							val = fm.Size > 0 ? strval.TrimEnd() : strval;
						}
					}
					else if( fm.Type == typeof(bool) && type != typeof(bool) )
					{
						// if property is boolean but database uses integers we need to convert
						// the type before updating it
						val = Convert.ToBoolean( val );
					}
					else if( fm.Type.IsEnum && ! type.IsEnum )
					{
						// check whether enum should be stored as string or numeric value
						// TODO we should check if enum requires 64-bit conversion 
						// val = fm.HandleEnumAsString ? Enum.Parse( fm.Type, Convert.ToString( val ), true ) : Enum.ToObject( fm.Type, Convert.ToInt32( val ) );
						val = Common.TypeConverter.Get( fm.Type, val );
					}
					else if( fm.Type == typeof(decimal) && type != typeof(decimal) )
					{
						val = Convert.ToDecimal( val, NumberFormatInfo.InvariantInfo );
					}
					else if( fm.Type != type )
					{
						TypeConverter typeConv = TypeDescriptor.GetConverter( fm.Type );
						if( typeConv != null && typeConv.CanConvertFrom( type ) )
						{
							val = typeConv.ConvertFrom( val );
						}
						else
						{
							// check for the existence of a TypeConverterAttribute for the field/property
							object[] attrs = fm.MemberInfo.GetCustomAttributes( typeof(TypeConverterAttribute), false );
							if( attrs.Length == 1 )
							{
								TypeConverterAttribute tca = (TypeConverterAttribute) attrs[ 0 ];
								TypeConverter typeConverter = (TypeConverter)
								                              Activator.CreateInstance( Type.GetType( tca.ConverterTypeName ) );
								if( typeConverter != null && typeConverter.CanConvertFrom( val.GetType() ) )
								{
									val = typeConverter.ConvertFrom( val );
								}
								else
								{
									val = Convert.ChangeType( val, fm.Type );
								}
							}
							else
							{
								val = Convert.ChangeType( val, fm.Type );
							}
						}
					}
				}
				else
				{
					// allow NullValue conversion for null strings
					if( fm.Type == typeof(string) && fm.NullValue != null )
					{
						val = fm.NullValue;
					}
				}
				return val;
			}
		}
Пример #22
0
		private void GetColumnData( TableMap map )
		{
			string sql = String.Format( selectColumns, map.TableName );
			SqlStatement stmt = broker.GetStatement( sql );
			stmt.StatementType = StatementType.Select;
			SqlResult sr = stmt.Execute();
			for( int i = 0; i < sr.Rows.Count; i++ )
			{
				// returns columns: Field, Type, TypeSize, FieldSize, NotNull, HasDefault, Default
				string columnName = sr.GetString( i, "field" );
				// get or create FieldMap for column
				FieldMap fm = map.GetFieldMapFromColumn( columnName );
				if( fm == null )
				{
					fm = new FieldMap( map, columnName );
					map.Fields.Add( fm );
				}
				bool isNullable = sr.GetString( i, "notnull" ).Trim().ToLower().StartsWith( "f" );
				if( fm != null )
				{
					bool hasDefault = sr.GetBoolean( i, "hasdefault" );
					fm.SetDbType( sr.GetString( i, "type" ), false );
					int size = ExtractSize( sr.GetInt( i, "typesize" ), sr.GetInt( i, "fieldsize" ) );
					fm.SetSize( size );
					fm.SetIsNullable( isNullable );
					//fm.SetIsPrimaryKey( sr.GetString( i, "Key" ).Equals( "PRI" ) );
					// fm.SetIsForeignKey( sr.GetString( i, "Key" ).Equals( "FOR" ) );
					//if( fm.IsPrimaryKey )
					//	fm.SetIsAutoGenerated( sr.GetString( i, "Key" ).Equals( "auto_increment" ) );
					//if( sr.GetString( i, "HasDefault" ).Equals( "t" ) )
					//	fm.SetMagicValue( sr.GetObject( i, "Default" ) );
				}
			}
		}
 private object ConvertType(FieldMap fm, object val)
 {
     Check.VerifyNotNull(fm, Error.NullParameter, "fm");
     // convert DBNull to system null
     if (val != null && val.Equals(DBNull.Value))
     {
         val = null;
     }
     // perform null handling (NullValue translation)
     if (val == null && !fm.IsNullAssignable)
     {
         Check.Verify(fm.NullValue != null, Error.NullWithNoNullValue, fm.ColumnName, fm.Type);
         return(fm.NullValue);
     }
     else
     {
         if (val != null)
         {
             Type type = val.GetType();
             // trim strings.. otherwise char columns are as wide as their size
             if (fm.Type == typeof(string) || fm.Type == typeof(Guid))
             {
                 if (fm.Type == typeof(Guid))
                 {
                     if (fm.Size == 16)                              // binary compressed version
                     {
                         val = Common.TypeConverter.ToGuid((string)val);
                     }
                     else
                     {
                         val = new Guid(val.ToString());
                     }
                 }
                 else
                 {
                     string strval = (string)val;
                     // size is 0 for variable width columns
                     // assume we should trim all fixed-width columns
                     val = fm.Size > 0 ? strval.TrimEnd() : strval;
                 }
             }
             else if (fm.Type == typeof(bool) && type != typeof(bool))
             {
                 // if property is boolean but database uses integers we need to convert
                 // the type before updating it
                 val = Convert.ToBoolean(val);
             }
             else if (fm.Type.IsEnum && !type.IsEnum)
             {
                 // check whether enum should be stored as string or numeric value
                 // TODO we should check if enum requires 64-bit conversion
                 // val = fm.HandleEnumAsString ? Enum.Parse( fm.Type, Convert.ToString( val ), true ) : Enum.ToObject( fm.Type, Convert.ToInt32( val ) );
                 val = Common.TypeConverter.Get(fm.Type, val);
             }
             else if (fm.Type == typeof(decimal) && type != typeof(decimal))
             {
                 val = Convert.ToDecimal(val, NumberFormatInfo.InvariantInfo);
             }
             else if (fm.Type != type)
             {
                 TypeConverter typeConv = TypeDescriptor.GetConverter(fm.Type);
                 if (typeConv != null && typeConv.CanConvertFrom(type))
                 {
                     val = typeConv.ConvertFrom(val);
                 }
                 else
                 {
                     // check for the existence of a TypeConverterAttribute for the field/property
                     object[] attrs = fm.MemberInfo.GetCustomAttributes(typeof(TypeConverterAttribute), false);
                     if (attrs.Length == 1)
                     {
                         TypeConverterAttribute tca           = (TypeConverterAttribute)attrs[0];
                         TypeConverter          typeConverter = (TypeConverter)
                                                                Activator.CreateInstance(Type.GetType(tca.ConverterTypeName));
                         if (typeConverter != null && typeConverter.CanConvertFrom(val.GetType()))
                         {
                             val = typeConverter.ConvertFrom(val);
                         }
                         else
                         {
                             val = Convert.ChangeType(val, fm.Type);
                         }
                     }
                     else
                     {
                         val = Convert.ChangeType(val, fm.Type);
                     }
                 }
             }
         }
         else
         {
             // allow NullValue conversion for null strings
             if (fm.Type == typeof(string) && fm.NullValue != null)
             {
                 val = fm.NullValue;
             }
         }
         return(val);
     }
 }
Пример #24
0
		private void GetColumnData( TableMap map )
		{
			string sql = String.Format( selectColumns, map.TableName );
			SqlStatement stmt = broker.GetStatement( sql );
			stmt.StatementType = StatementType.Select;
			SqlResult sr = stmt.Execute();
			for( int i = 0; i < sr.Rows.Count; i++ )
			{
				// returns columns: Field, Type, Null, Key, Default, Extra
				string columnName = sr.GetString( i, "Field" );
				FieldMap fm = map.GetFieldMapFromColumn( columnName );
				if( fm == null )
				{
					fm = new FieldMap( map, columnName );
					map.Fields.Add( fm );
				}
				if( fm != null )
				{
					string typeinfo = sr.GetString( i, "Type" );
					bool isUnsigned;
					fm.SetDbType( ExtractType( typeinfo, out isUnsigned ), isUnsigned );
					if( fm.DbType == (long) MySqlDbType.Enum )
					{
						fm.HandleEnumAsString = true;
					}
					fm.SetSize( ExtractSize( typeinfo ) );
					fm.SetIsNullable( sr.GetString( i, "Null" ).Equals( "YES" ) );
					fm.SetIsPrimaryKey( sr.GetString( i, "Key" ).Equals( "PRI" ) );
					if( fm.IsPrimaryKey )
					{
						fm.SetIsAutoGenerated( sr.GetString( i, "Extra" ).Equals( "auto_increment" ) );
					}
				}
				else // raise an error if we've detected a database/type mismatch
				{
					bool hasDefault = sr.GetObject( i, "Default" ) != null;
					// TODO disabled due to code restructuring 
					// Check.Verify( isNullable || hasDefault, Error.NoPropertyForNotNullColumn, column, map.Type );
				}
			}
		}
Пример #25
0
        public void RemoveAt(int index)
        {
            FieldMap fm = fields[index] as FieldMap;

            Remove(fm);
        }
Пример #26
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);
        }
Пример #27
0
		private void UpdateTableMapWithColumnInformation( TableMap map )
		{
			SqlResult sr = broker.Execute( String.Format( selectColumns, map.TableName ), null, null );
			// process result set using columns: cid, name, type, notnull, dflt_value, pk			
			for( int i=0; i<sr.RowsContained; i++ )
			{
				string columnName = sr.GetString( i, "name" );
				FieldMap fm = map.GetFieldMapFromColumn( columnName );
				if( fm == null )
				{
					fm = new FieldMap( map, columnName );
					map.Fields.Add( fm );
				}
				// get basic column information
				fm.SetDbType( sr.GetString( i, "type" ), false );
				fm.SetIsNullable( ! sr.GetBoolean( i, "notnull" ) );
				fm.SetIsPrimaryKey( sr.GetBoolean( i, "pk" ) );
				fm.SetIsAutoGenerated( fm.IsPrimaryKey && (fm.Type == typeof(int) || fm.Type == typeof(long)) );
			}
		}
Пример #28
0
		/// <summary>
		/// This method fills the TableMap with information on table columns.
		/// </summary>
		private void GetColumnData( TableMap map )
		{
			DataTable dt = GetColumns( map.TableName );
			foreach( DataRow row in dt.Rows )
			{
				// result row contains:
				// COLUMN_NAME, DATA_TYPE, ORDINAL_POSITION, COLUMN_HASDEFAULT, COLUMN_DEFAULT, 
				// COLUMN_FLAGS, IS_NULLABLE, NUMERIC_PRECISION, NUMERIC_SCALE, 
				// CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH
				string columnName = (string) row[ "COLUMN_NAME" ];
				FieldMap fm = map.GetFieldMapFromColumn( columnName );
				if( fm == null )
				{
					fm = new FieldMap( map, columnName );
					map.Fields.Add( fm );
				}
				bool isNullable = Convert.ToBoolean( row[ "IS_NULLABLE" ] );
				if( fm != null )
				{
					OleDbType dbType = (OleDbType) row[ "DATA_TYPE" ];
					fm.SetDbType( (long) dbType );
					// set numeric scale for DBTYPE_DECIMAL, DBTYPE_NUMERIC, DBTYPE_VARNUMERIC
					if( dbType == OleDbType.Decimal || dbType == OleDbType.Numeric || dbType == OleDbType.VarNumeric )
					{
						fm.SetSize( Convert.ToInt32( row[ "NUMERIC_PRECISION" ] ) );
					}
					if( dbType == OleDbType.LongVarBinary || dbType == OleDbType.LongVarChar ||
					    dbType == OleDbType.LongVarWChar || dbType == OleDbType.VarBinary ||
					    dbType == OleDbType.VarChar || dbType == OleDbType.VarWChar ||
					    dbType == OleDbType.WChar || dbType == OleDbType.Char || dbType == OleDbType.BSTR ||
					    dbType == OleDbType.Binary )
					{
						fm.SetSize( Convert.ToInt32( row[ "CHARACTER_MAXIMUM_LENGTH" ] ) );
					}
					fm.SetIsNullable( isNullable );

					int columnFlags = Convert.ToInt32( row[ "COLUMN_FLAGS" ] );

					// BROKEN (expected value does not match IS_NULLABLE set above)
					// BROKEN set whether column can contain NULL values
					int flags = (int) DBCOLUMNFLAGS.ISNULLABLE + (int) DBCOLUMNFLAGS.MAYBENULL;
					bool isNullableFlag = (columnFlags & flags) != 0;
					//fm.SetIsNullable( isNullableFlag && fm.IsNullable );

					// set whether column is updatable
					flags = (int) DBCOLUMNFLAGS.WRITE + (int) DBCOLUMNFLAGS.WRITEUNKNOWN;
					bool isReadOnly = (columnFlags & flags) == 0;
					fm.IsReadOnly = isReadOnly;

					// BROKEN (expected bitmask value is never set)
					// set whether column is auto-generated
					//flags = (int) DBCOLUMNFLAGS.ISROWID;
					//bool isAutoGenerated = (columnFlags & flags) != 0;
					//fm.SetIsAutoGenerated( isAutoGenerated );				
				}
				else // raise an error if we've detected a database/type mismatch
				{
					bool hasDefault = Convert.ToBoolean( row[ "COLUMN_HASDEFAULT" ] );
					// TODO disabled due to code restructuring 
					Check.Verify( isNullable || hasDefault, Error.NoPropertyForNotNullColumn, columnName, map.TableName );
				}
			}
		}