protected void GetIdentityInformation( TableMap map )
		{
			if( map != null )
			{
				// also obtain identity column information
				GentleSqlFactory sf = provider.GetSqlFactory();
				try
				{
					string tableName = sf.GetTableName( map.TableName );
					foreach( FieldMap fm in map.Fields )
					{
						if( fm.IsPrimaryKey )
						{
							if( ! map.IsView )
							{
								SqlResult sr = broker.Execute( String.Format( selectIdentityInfo, tableName, fm.ColumnName ) );
								fm.SetIsAutoGenerated( sr.GetInt( 0, "IsIdentity" ) == 1 );
							}
						}
					}
				}
				catch( Exception e )
				{
					Check.LogWarning( LogCategories.Metadata, "Unable to determine whether PK column of table {0} is an identity column.",
					                  map.TableName );
					Check.LogWarning( LogCategories.Metadata, e.Message );
				}
			}
		}
示例#2
0
		public override void Analyze( string tableName )
		{
			try
			{
				bool isSingleRun = tableName != null;
				SqlStatement stmt = broker.GetStatement( selectTables );
				stmt.StatementType = StatementType.Select;
				SqlResult sr = stmt.Execute();
				for( int i = 0; i < sr.Rows.Count; i++ )
				{
					try
					{
						string dbTableName = sr.GetString( i, 0 );
						if( ! isSingleRun || tableName.ToLower().Equals( dbTableName.ToLower() ) )
						{
							TableMap map = GetTableMap( dbTableName );
							if( map == null )
							{
								map = new TableMap( provider, dbTableName );
								maps[ dbTableName.ToLower() ] = map;
							}
							// TODO: get column information for this table

							// TODO: get foreign key information

							// abort loop if analyzing single table only
							if( isSingleRun )
							{
								break;
							}
						}
					}
					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." );
			}
		}
示例#3
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;
				string sql = isSingleRun ? String.Format( "{0} and name = '{1}'", selectTables, tableName ) : selectTables;
				SqlResult sr = broker.Execute( sql, null, null );
				for( int row=0; row<sr.RowsContained; row++ )
				{
					tableName = sr.GetString( row, 0 );
					// get TableMap for current table
					TableMap map = GetTableMap( tableName );
					if( map == null )
					{
						map = new TableMap( provider, tableName );
						maps[ tableName.ToLower() ] = map;
					}
					// get column information 
					UpdateTableMapWithColumnInformation( map );
					// get foreign key information
					UpdateTableMapWithForeignKeyInformation( map );
				}
			}
			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." );
			}
		}
示例#4
0
		/// <summary>
		/// Obtain a list of <see cref="FieldMap"/> instances that represent foreign key
		/// references to fields on the supplied parent object.
		/// </summary>
		/// <param name="parentMap">The map of the type the foreign key fields should reference
		/// if they are to be included in the result.</param>
		/// <param name="isPrimaryKeysOnly">True if only foreign keys pointing to primary keys
		/// should be included, false to include all foreign key references.</param>
		/// <returns>A list of FieldMap instances or an empty list id no fields matched.</returns>
		public Hashtable GetForeignKeyMappings( TableMap parentMap, bool isPrimaryKeysOnly )
		{
			Hashtable result = new Hashtable();
			foreach( FieldMap child in fields )
			{
				if( child.IsForeignKey )
				{
					foreach( FieldMap parent in parentMap.Fields )
					{
						bool isSameTable = String.Compare( child.ForeignKeyTableName, parentMap.TableName, true ) == 0;
						isSameTable |= String.Compare( child.ForeignKeyTableName, parentMap.QuotedTableName, true ) == 0;
						if( isSameTable && String.Compare( child.ForeignKeyColumnName, parent.ColumnName, true ) == 0 )
						{
							bool isPK = child.IsPrimaryKey || parent.IsPrimaryKey;
							if( ! isPrimaryKeysOnly || (isPrimaryKeysOnly && isPK) )
							{
								result[ child ] = parent;
							}
						}
					}
				}
			}
			Check.Verify( result.Count > 0, Error.DeveloperError,
			              String.Format( "The table {0} has no foreign keys pointing to table {1}.",
			                             tableName, parentMap.TableName ) );
			return result;
		}
示例#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 )
		{
			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." );
			}
		}
示例#6
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." );
			}
		}
示例#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 );
				bool isNullable = sr.GetString( i, "nulls" ).Equals( "Y" );
				if( fm != null )
				{
					fm.ColumnId = sr.GetInt( i, "column_id" );
					fm.SetDbType( sr.GetString( i, "domain_name" ), false );
					fm.SetIsNullable( isNullable );
					fm.SetSize( sr.GetInt( i, "width" ) );
				}
				else // raise an error if we've detected a database/type mismatch
				{
					// TODO disabled due to code restructuring
					// Check.Verify( isNullable, Error.NoPropertyForNotNullColumn, column, map.Type );
				}
			}
		}
示例#8
0
		private void GetColumnConstraints( TableMap map )
		{
			// primary key
			string sql = String.Format( selectPrimaryKeyConstraints, map.TableId );
			SqlResult sr = broker.Execute( sql );
			if( sr.Rows.Count > 0 )
			{
				int columnId = sr.GetInt( 0, "column_id" );
				FieldMap fm = map.Fields.FindColumnById( columnId );
				if( fm != null )
				{
					fm.SetIsPrimaryKey( true );
				}
			}
			// foreign key
			sql = String.Format( selectForeignKeyConstraints, map.TableId );
			sr = broker.Execute( sql );
			for( int i = 0; i < sr.Rows.Count; i++ )
			{
				int columnId = sr.GetInt( i, "column_id" );
				FieldMap fm = map.Fields.FindColumnById( columnId );
				if( fm != null )
				{
					fm.SetForeignKeyTableName( sr.GetString( i, "FT" ) );
					fm.SetForeignKeyColumnName( sr.GetString( i, "FK" ) );
				}
			}
		}
示例#9
0
		private void UpdateTableMapWithForeignKeyInformation( TableMap map )
		{
			SqlResult sr = broker.Execute( String.Format( selectForeignKeys, map.TableName ), null, null );
			// process result set using columns: ??
			for( int i=0; i<sr.RowsContained; i++ )
			{
				//string type = sr.GetString( i, "ConstraintType" );
				//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." );
				//        }
				//    }
				//}
			}
		}
示例#10
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;
					}
				}
			}
		}
示例#11
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." );
			}
		}
示例#12
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 );
				}
			}
		}
示例#13
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" ) );
			}
		}
示例#14
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());
         }
     }
 }
示例#15
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 );
				}
			}
		}
示例#16
0
		private void GetConstraintData( TableMap map )
		{
			SqlStatement stmt = broker.GetStatement( String.Format( selectConstraints, map.TableName ) );
			stmt.StatementType = StatementType.Select;
			SqlResult sr = stmt.Execute();
			if( sr.Rows.Count == 1 )
			{
				// returns columns: Name, Type, Row_format, Rows, Avg_row_length, Data_length, Max_data_length,
				//   Index_length, Data_free, Auto_increment, Create_time, Update_time, Check_time, Create_options,
				//   Comment (as "InnoDB free: 3072 kB; (ListId) REFER test/List(ListId)"		 
				string comment = sr.GetString( 0, 1 ); // column 1 is either "Create table" or "Create view" 
				if( comment != null && comment.Length > 5 )
				{
					string[] comments = comment.Split( ',' );
					foreach( string cmt in comments )
					{
						string tmp = cmt.Trim();
						// samples:
						// "(Column) REFER database/Table(Column)"
						// "(`Column`) REFER `database/Table`(`Column`)"
						string pattern = @"\(`?(?<column>\w+)`?\) REFER .*/(?<fkTable>\w+)[`\s]+\(`?(?<fkColumn>\w+)`?\)";
						Regex regex = new Regex( pattern, RegexOptions.ExplicitCapture | RegexOptions.Compiled );
						Match m = regex.Match( tmp );
						if( m.Success )
						{
							FieldMap fm = map.GetFieldMapFromColumn( m.Groups[ "column" ].Value );
							if( fm != null )
							{
								fm.SetForeignKeyTableName( m.Groups[ "fkTable" ].Value );
								fm.SetForeignKeyColumnName( m.Groups[ "fkColumn" ].Value );
							}
						}
						else
						{
							//CONSTRAINT `fk_employee_type_employee` FOREIGN KEY (`employee_type_id`) REFERENCES `employee_type` (`employee_type_id`) ON DELETE CASCADE ON UPDATE CASCADE
							pattern = @"[\s\w]FOREIGN KEY\s\(`?(?<column>\w+)`?\) REFERENCES `?(?<fkTable>\w+)`? \(`?(?<fkColumn>\w+)`?\)[\s\w]+";
							Regex regexNew = new Regex( pattern, RegexOptions.ExplicitCapture | RegexOptions.Compiled );
							Match mNew = regexNew.Match( tmp );
							if( mNew.Success )
							{
								// string constraintPart = mNew.Groups["constraint"].Value;
								FieldMap fm = map.GetFieldMapFromColumn( mNew.Groups[ "column" ].Value );
								if( fm != null )
								{
									fm.SetForeignKeyTableName( mNew.Groups[ "fkTable" ].Value );
									fm.SetForeignKeyColumnName( mNew.Groups[ "fkColumn" ].Value );
								}
							}
							else if( tmp != null )
							{
								int index = tmp.IndexOf( "REFER" );
								if( index > 0 )
								{
									string columnName = ExtractColumn( tmp.Substring( 0, index - 1 ) );
									tmp = tmp.Substring( index + 5, tmp.Length - index - 5 ).Trim();
									index = tmp.IndexOf( "/" );
									int start = tmp.IndexOf( "(" );
									int end = tmp.IndexOf( ")" );
									if( index > 0 && start > 0 && end > start )
									{
										string foreignTable = tmp.Substring( index + 1, start - index - 1 );
										string foreignColumn = tmp.Substring( start + 1, end - start - 1 );
										FieldMap fm = map.GetFieldMapFromColumn( columnName );
										fm.SetForeignKeyTableName( foreignTable );
										fm.SetForeignKeyColumnName( foreignColumn );
									}
								}
							}
						}
					}
				}
			}
		}
示例#17
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" ) );
				}
			}
		}
示例#18
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)) );
			}
		}
示例#19
0
 /// <summary>
 /// Constructor for fields using information obtained directly from the database (no property info).
 /// </summary>
 public FieldMap(TableMap map, string columnName)
 {
     this.map = map;
     SetColumnName(columnName);
 }
示例#20
0
		private void UpdateTableMapWithIndexInformation( TableMap map )
		{
			SqlResult sr = broker.Execute( String.Format( selectIndexes, map.TableName ), null, null );
			// process result set using columns: name, unique		
			for( int i=0; i<sr.RowsContained; i++ )
			{
				string indexName = sr.GetString( i, "name" );

				SqlResult indexInfo = broker.Execute( String.Format( selectIndex, map.TableName ), null, null );
				// process result set using columns: seqno, cid, name		
				for( int indexColumn=0; indexColumn<sr.RowsContained; indexColumn++ )
				{
					// fm.SetIsAutoGenerated( sr.GetString( i, "dflt_value" ).Length > 0 ? true : false );
				}
			}
		}
示例#21
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;
             }
         }
     }
 }
示例#22
0
		public override void Analyze( string tableName )
		{
			try
			{
				bool isSingleRun = tableName != null;
				DataTable dt = GetTables( tableName );
				foreach( DataRow row in dt.Rows )
				{
					try
					{
						string dbTableName = (string) row[ "TABLE_NAME" ];
						// skip Access system tables
						if( ! dbTableName.StartsWith( "MSysAccess" ) )
						{
							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
								GetColumnData( map );
								// abort loop if analyzing single table only
								if( isSingleRun )
								{
									break;
								}
							}
						}
					}
					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;
						}
					}
				}
				// get information on primary and foreign keys (for tables found here)
				GetPrimaryKeyData();
				GetForeignKeyData();
			}
			catch( Exception e )
			{
				Check.Fail( e, Error.Unspecified, "An error occurred while analyzing the database schema." );
			}
		}
示例#23
0
		/// <summary>
		/// Constructor for fields using information obtained directly from the database (no property info).
		/// </summary>
		public FieldMap( TableMap map, string columnName )
		{
			this.map = map;
			SetColumnName( columnName );
		}