@@ -384,112 +384,139 @@ public override string[] GetTables()
384384
385385 public override Column [ ] GetColumns ( string table )
386386 {
387+ var stringBuilder = new StringBuilder ( ) ;
388+ stringBuilder . AppendLine ( "SELECT" ) ;
389+ stringBuilder . AppendLine ( " COLUMN_NAME," ) ;
390+ stringBuilder . AppendLine ( " NULLABLE," ) ;
391+ stringBuilder . AppendLine ( " DATA_DEFAULT," ) ;
392+ stringBuilder . AppendLine ( " DATA_TYPE," ) ;
393+ stringBuilder . AppendLine ( " DATA_PRECISION," ) ;
394+ stringBuilder . AppendLine ( " DATA_SCALE," ) ;
395+ stringBuilder . AppendLine ( " CHAR_COL_DECL_LENGTH" ) ;
396+ stringBuilder . AppendLine ( $ "FROM USER_TAB_COLUMNS WHERE LOWER(TABLE_NAME) = LOWER('{ table } ')") ;
397+
387398 var columns = new List < Column > ( ) ;
388399
389400 using ( var cmd = CreateCommand ( ) )
390- using (
391- var reader =
392- ExecuteQuery ( cmd ,
393- string . Format (
394- "select column_name, data_type, data_length, data_precision, data_scale, NULLABLE, data_default FROM USER_TAB_COLUMNS WHERE lower(table_name) = '{0}'" ,
395- table . ToLower ( ) ) ) )
401+ using ( var reader = ExecuteQuery ( cmd , stringBuilder . ToString ( ) ) )
396402 {
397403 while ( reader . Read ( ) )
398404 {
399- var colName = reader [ 0 ] . ToString ( ) ;
400- var colType = DbType . String ;
401- var dataType = reader [ 1 ] . ToString ( ) . ToLower ( ) ;
402- var isNullable = ParseBoolean ( reader . GetValue ( 5 ) ) ;
403- var defaultValue = reader . GetValue ( 6 ) ;
405+ var columnNameOrdinal = reader . GetOrdinal ( "COLUMN_NAME" ) ;
406+ var nullableOrdinal = reader . GetOrdinal ( "NULLABLE" ) ;
407+ var dataDefaultOrdinal = reader . GetOrdinal ( "DATA_DEFAULT" ) ;
408+ var dataTypeOrdinal = reader . GetOrdinal ( "DATA_TYPE" ) ;
409+ var dataPrecisionOrdinal = reader . GetOrdinal ( "DATA_PRECISION" ) ;
410+ var dataScaleOrdinal = reader . GetOrdinal ( "DATA_SCALE" ) ;
411+ var charColDeclLengthOrdinal = reader . GetOrdinal ( "CHAR_COL_DECL_LENGTH" ) ;
412+
413+ var columnName = reader . GetString ( columnNameOrdinal ) ;
414+ var isNullable = reader . GetString ( nullableOrdinal ) == "Y" ? true : false ;
415+ var dataDefaultString = reader . GetString ( dataDefaultOrdinal ) ;
416+ var dataTypeString = reader . GetString ( dataTypeOrdinal ) ;
417+ var dataPrecision = reader . IsDBNull ( dataPrecisionOrdinal ) ? ( int ? ) null : reader . GetInt32 ( dataPrecisionOrdinal ) ;
418+ var dataScale = reader . IsDBNull ( dataScaleOrdinal ) ? ( int ? ) null : reader . GetInt32 ( dataScaleOrdinal ) ;
419+ var charColDeclLength = reader . IsDBNull ( charColDeclLengthOrdinal ) ? ( int ? ) null : reader . GetInt32 ( charColDeclLengthOrdinal ) ;
420+
421+ var column = new Column ( columnName , DbType . String )
422+ {
423+ ColumnProperty = isNullable ? ColumnProperty . Null : ColumnProperty . NotNull
424+ } ;
404425
405- if ( dataType . Equals ( "number" ) )
426+ if ( dataTypeString == "number" )
406427 {
407- var precision = Convert . ToInt32 ( reader . GetValue ( 3 ) ) ;
408- var scale = Convert . ToInt32 ( reader . GetValue ( 4 ) ) ;
409- if ( scale == 0 )
428+ var precision = dataPrecision ;
429+ var scale = dataScale ;
430+
431+ if ( scale > 0 )
410432 {
411- colType = precision <= 10 ? DbType . Int16 : DbType . Int64 ;
433+ column . MigratorDbType = MigratorDbType . Decimal ;
412434 }
413435 else
414436 {
415- colType = DbType . Decimal ;
437+ if ( 0 <= precision && precision <= 4 )
438+ {
439+ column . MigratorDbType = MigratorDbType . Int16 ;
440+ }
441+ else if ( 5 <= precision && precision <= 10 )
442+ {
443+ column . MigratorDbType = MigratorDbType . Int32 ;
444+ }
445+ else if ( 10 <= precision && precision <= 18 )
446+ {
447+ column . MigratorDbType = MigratorDbType . Int64 ;
448+ }
449+ else
450+ {
451+ throw new NotSupportedException ( "No support for greater numbers than 18 digits" ) ;
452+ }
416453 }
417454 }
418- else if ( dataType . StartsWith ( "timestamp " ) || dataType . Equals ( "date" ) )
455+ else if ( dataTypeString . StartsWith ( "TIMESTAMP " ) || dataTypeString . Equals ( "date" ) )
419456 {
420- colType = DbType . DateTime ;
457+ column . MigratorDbType = MigratorDbType . DateTime ;
421458 }
422459
423- var columnProperties = ( isNullable ) ? ColumnProperty . Null : ColumnProperty . NotNull ;
424- var column = new Column ( colName , colType , columnProperties ) ;
425-
426- if ( defaultValue != null && defaultValue != DBNull . Value )
427- {
428- column . DefaultValue = defaultValue ;
429- }
430-
431- if ( column . DefaultValue is string && ( ( string ) column . DefaultValue ) . StartsWith ( "'" ) && ( ( string ) column . DefaultValue ) . EndsWith ( "'" ) )
432- {
433- column . DefaultValue = ( ( string ) column . DefaultValue ) . Substring ( 1 , ( ( string ) column . DefaultValue ) . Length - 2 ) ;
434- }
435-
436- if ( ( column . DefaultValue is string s && ! string . IsNullOrEmpty ( s ) ) ||
437- column . DefaultValue is not string && column . DefaultValue != null )
460+ if ( dataDefaultString != null )
438461 {
439- if ( column . Type == DbType . Int16 || column . Type == DbType . Int32 || column . Type == DbType . Int64 )
462+ if ( ( column . DefaultValue is string s && ! string . IsNullOrEmpty ( s ) ) ||
463+ column . DefaultValue is not string && column . DefaultValue != null )
440464 {
441- column . DefaultValue = long . Parse ( column . DefaultValue . ToString ( ) ) ;
442- }
443- else if ( column . Type == DbType . UInt16 || column . Type == DbType . UInt32 || column . Type == DbType . UInt64 )
444- {
445- column . DefaultValue = ulong . Parse ( column . DefaultValue . ToString ( ) ) ;
446- }
447- else if ( column . Type == DbType . Double || column . Type == DbType . Single )
448- {
449- column . DefaultValue = double . Parse ( column . DefaultValue . ToString ( ) ) ;
450- }
451- else if ( column . Type == DbType . Boolean )
452- {
453- column . DefaultValue = column . DefaultValue . ToString ( ) . Trim ( ) == "1" || column . DefaultValue . ToString ( ) . Trim ( ) . ToUpper ( ) == "TRUE" ;
454- }
455- else if ( column . Type == DbType . DateTime || column . Type == DbType . DateTime2 )
456- {
457- if ( column . DefaultValue is string defValCv && defValCv . StartsWith ( "TO_TIMESTAMP(" ) )
465+ if ( column . Type == DbType . Int16 || column . Type == DbType . Int32 || column . Type == DbType . Int64 )
458466 {
459- var dt = defValCv . Substring ( ( defValCv . IndexOf ( "'" ) + 1 ) , defValCv . IndexOf ( "'" , defValCv . IndexOf ( "'" ) + 1 ) - defValCv . IndexOf ( "'" ) - 1 ) ;
460- var d = DateTime . ParseExact ( dt , "yyyy-MM-dd HH:mm:ss.ff" , CultureInfo . InvariantCulture ) ;
461- column . DefaultValue = d ;
467+ column . DefaultValue = long . Parse ( column . DefaultValue . ToString ( ) ) ;
462468 }
463- else if ( column . DefaultValue is string defVal )
469+ else if ( column . Type == DbType . UInt16 || column . Type == DbType . UInt32 || column . Type == DbType . UInt64 )
464470 {
465- var dt = defVal ;
466- if ( defVal . StartsWith ( "'" ) )
467- {
468- dt = defVal . Substring ( 1 , defVal . Length - 2 ) ;
469- }
470-
471- var d = DateTime . ParseExact ( dt , "yyyy-MM-dd HH:mm:ss" , CultureInfo . InvariantCulture ) ;
472- column . DefaultValue = d ;
471+ column . DefaultValue = ulong . Parse ( column . DefaultValue . ToString ( ) ) ;
473472 }
474- }
475- else if ( column . Type == DbType . Guid )
476- {
477- if ( column . DefaultValue is string defValCv && defValCv . StartsWith ( "HEXTORAW(" ) )
473+ else if ( column . Type == DbType . Double || column . Type == DbType . Single )
474+ {
475+ column . DefaultValue = double . Parse ( column . DefaultValue . ToString ( ) ) ;
476+ }
477+ else if ( column . Type == DbType . Boolean )
478478 {
479- var dt = defValCv . Substring ( ( defValCv . IndexOf ( "'" ) + 1 ) , defValCv . IndexOf ( "'" , defValCv . IndexOf ( "'" ) + 1 ) - defValCv . IndexOf ( "'" ) - 1 ) ;
480- var d = Guid . Parse ( dt ) ;
481- column . DefaultValue = d ;
479+ column . DefaultValue = column . DefaultValue . ToString ( ) . Trim ( ) == "1" || column . DefaultValue . ToString ( ) . Trim ( ) . ToUpper ( ) == "TRUE" ;
482480 }
483- else if ( column . DefaultValue is string defVal )
481+ else if ( column . Type == DbType . DateTime || column . Type == DbType . DateTime2 )
484482 {
485- var dt = defVal ;
486- if ( defVal . StartsWith ( "'" ) )
483+ if ( column . DefaultValue is string defValCv && defValCv . StartsWith ( "TO_TIMESTAMP(" ) )
487484 {
488- dt = defVal . Substring ( 1 , defVal . Length - 2 ) ;
485+ var dt = defValCv . Substring ( ( defValCv . IndexOf ( "'" ) + 1 ) , defValCv . IndexOf ( "'" , defValCv . IndexOf ( "'" ) + 1 ) - defValCv . IndexOf ( "'" ) - 1 ) ;
486+ var d = DateTime . ParseExact ( dt , "yyyy-MM-dd HH:mm:ss.ff" , CultureInfo . InvariantCulture ) ;
487+ column . DefaultValue = d ;
488+ }
489+ else if ( column . DefaultValue is string defVal )
490+ {
491+ var dt = defVal ;
492+ if ( defVal . StartsWith ( "'" ) )
493+ {
494+ dt = defVal . Substring ( 1 , defVal . Length - 2 ) ;
495+ }
496+
497+ var d = DateTime . ParseExact ( dt , "yyyy-MM-dd HH:mm:ss" , CultureInfo . InvariantCulture ) ;
498+ column . DefaultValue = d ;
499+ }
500+ }
501+ else if ( column . Type == DbType . Guid )
502+ {
503+ if ( column . DefaultValue is string defValCv && defValCv . StartsWith ( "HEXTORAW(" ) )
504+ {
505+ var dt = defValCv . Substring ( ( defValCv . IndexOf ( "'" ) + 1 ) , defValCv . IndexOf ( "'" , defValCv . IndexOf ( "'" ) + 1 ) - defValCv . IndexOf ( "'" ) - 1 ) ;
506+ var d = Guid . Parse ( dt ) ;
507+ column . DefaultValue = d ;
508+ }
509+ else if ( column . DefaultValue is string defVal )
510+ {
511+ var dt = defVal ;
512+ if ( defVal . StartsWith ( "'" ) )
513+ {
514+ dt = defVal . Substring ( 1 , defVal . Length - 2 ) ;
515+ }
516+
517+ var d = Guid . Parse ( dt ) ;
518+ column . DefaultValue = d ;
489519 }
490-
491- var d = Guid . Parse ( dt ) ;
492- column . DefaultValue = d ;
493520 }
494521 }
495522 }
@@ -501,24 +528,6 @@ public override Column[] GetColumns(string table)
501528 return columns . ToArray ( ) ;
502529 }
503530
504- private bool ParseBoolean ( object value )
505- {
506- if ( value is string )
507- {
508- if ( "N" == ( string ) value )
509- {
510- return false ;
511- }
512-
513- if ( "Y" == ( string ) value )
514- {
515- return true ;
516- }
517- }
518-
519- return Convert . ToBoolean ( value ) ;
520- }
521-
522531 public override string GenerateParameterNameParameter ( int index )
523532 {
524533 return "p" + index ;
0 commit comments