Class: IBRuby::InterBaseColumn

Inherits:
Object
  • Object
show all
Defined in:
lib/ibmeta.rb

Overview

This class is used to represent SQL table column tables.

Constant Summary collapse

BOOLEAN =

A definition for a base SQL type.

:BOOLEAN
BLOB =

A definition for a base SQL type.

:BLOB
CHAR =

A definition for a base SQL type.

:CHAR
DATE =

A definition for a base SQL type.

:DATE
DECIMAL =

A definition for a base SQL type.

:DECIMAL
DOUBLE =

A definition for a base SQL type.

:DOUBLE
FLOAT =

A definition for a base SQL type.

:FLOAT
INTEGER =

A definition for a base SQL type.

:INTEGER
NUMERIC =

A definition for a base SQL type.

:NUMERIC
SMALLINT =

A definition for a base SQL type.

:SMALLINT
TIME =

A definition for a base SQL type.

:TIME
TIMESTAMP =

A definition for a base SQL type.

:TIMESTAMP
VARCHAR =

A definition for a base SQL type.

:VARCHAR
INT64 =

data type can be returned when arithmetic occurs, e.g. SMALLINT * -1 returns a INT64

:INT64
@@default_precision =

allow these to be overriden

10
@@default_scale =
2
@@default_length =

so string indexes work by default

252

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(column_name, table_name, type, default_source = nil, not_null = false, length = nil, precision = 10, scale = 0, sub_type = nil, actual_default = nil) ⇒ InterBaseColumn

This is the constructor for the InterBaseColumn class.

Parameters

type

The base type for the InterBaseColumn object. Must be one of the base types defined within the class.

length

The length setting for the type. Defaults to nil.

precision

The precision setting for the type. Defaults to nil.

scale

The scale setting for the type. Defaults to nil.

sub_type

The SQL sub-type setting. Defaults to nil.

default_source

the whole string “default xxx” or “default ‘xxx’”

not_null: true for NOT NULL, false for nulls allowed

actual_default

if specified then we don’t bother processing default_source



583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/ibmeta.rb', line 583

def initialize(column_name, table_name, type, default_source=nil, not_null=false, 
      length=nil, precision=10, scale=0, sub_type=nil, actual_default=nil )
  @name = column_name
  @table_name = table_name
  @not_null = not_null
  @type      = type
  @length    = length
  @precision = precision
  @scale     = scale
  @sub_type  = sub_type

  
  if !actual_default.nil?
    #puts "actual default #{actual_default}"
    @default = actual_default
  else
    validate_default_source(default_source)
  end
end

Instance Attribute Details

#defaultObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def default
  @default
end

#lengthObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def length
  @length
end

#nameObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def name
  @name
end

#not_nullObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def not_null
  @not_null
end

#precisionObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def precision
  @precision
end

#scaleObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def scale
  @scale
end

#sub_typeObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def sub_type
  @sub_type
end

#table_nameObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def table_name
  @table_name
end

#typeObject

Attribute accessor.



552
553
554
# File 'lib/ibmeta.rb', line 552

def type
  @type
end

Class Method Details

.expects_quoting(col) ⇒ Object



554
555
556
557
558
559
560
561
562
563
564
565
# File 'lib/ibmeta.rb', line 554

def self.expects_quoting(col)
  case col.type
    when InterBaseColumn::NUMERIC, InterBaseColumn::DECIMAL, InterBaseColumn::INTEGER, 
            InterBaseColumn::DOUBLE, InterBaseColumn::FLOAT
      false
    when InterBaseColumn::CHAR, InterBaseColumn::VARCHAR, InterBaseColumn::BLOB, 
            InterBaseColumn::DATE, InterBaseColumn::TIME, InterBaseColumn::TIMESTAMP
      true
    else
      nil
  end
end

.to_base_type(type, subtype) ⇒ Object

This class method converts a InterBase internal type to a InterBaseColumn base type.

Parameters

type

A reference to the Interbase field type value.

sub_type

A reference to the Interbase field subtype value.



710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
# File 'lib/ibmeta.rb', line 710

def self.to_base_type(type, subtype)
  case type
  when 16  #  DECIMAL, NUMERIC
    if subtype
      subtype == 1 ? InterBaseColumn::NUMERIC : InterBaseColumn::DECIMAL
    else
      InterBaseColumn::INT64 # can't actually define a column of this type
    end
  when 17  # BOOLEAN
    InterBaseColumn::BOOLEAN
    
  when 261 # BLOB
    InterBaseColumn::BLOB
    
  when 14  # CHAR
    InterBaseColumn::CHAR
    
  when 12  # DATE
    InterBaseColumn::DATE
    
  when 27  # DOUBLE, DECIMAL, NUMERIC
    if subtype
      subtype == 1 ? InterBaseColumn::NUMERIC : InterBaseColumn::DECIMAL
    else
      InterBaseColumn::DOUBLE
    end
    
  when 10  # FLOAT
    InterBaseColumn::FLOAT
    
  when 8   # INTEGER, DECIMAL, NUMERIC
    if subtype
      subtype == 1 ? InterBaseColumn::NUMERIC : InterBaseColumn::DECIMAL
    else
      InterBaseColumn::INTEGER
    end
    
  when 7   # SMALLINT, DECIMAL, NUMERIC
    if subtype
      subtype == 1 ? InterBaseColumn::NUMERIC : InterBaseColumn::DECIMAL
    else
      InterBaseColumn::SMALLINT
    end
    
  when 13  # TIME
    InterBaseColumn::TIME
    
  when 35  # TIMESTAMP
    InterBaseColumn::TIMESTAMP
    
  when 37  # VARCHAR
    InterBaseColumn::VARCHAR
  end
end

Instance Method Details

#==(object) ⇒ Object

This method overloads the equivalence test operator for the InterBaseColumn class.

Parameters

object

A reference to the object to be compared with.



654
655
656
657
658
659
660
661
662
663
664
# File 'lib/ibmeta.rb', line 654

def ==(object)
  result = false
  if object.instance_of?(InterBaseColumn)
    result = (@type      == object.type &&
              @length    == object.length &&
              @precision == object.precision &&
              @scale     == object.scale &&
              @sub_type   == object.sub_type)
  end
  result
end

#add_column(connection) ⇒ Object

this column does not exist in the database, please create it!



773
774
775
776
777
# File 'lib/ibmeta.rb', line 773

def add_column( connection )
  validate  # ensure sensible defaults
  #puts "alter table #{@table_name} add #{self.to_sql}"
  connection.execute_immediate( "alter table #{@table_name} add #{self.to_sql}" )
end

#change_column(conn, new_column) ⇒ Object



779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
# File 'lib/ibmeta.rb', line 779

def change_column(conn, new_column)
  new_column.validate  # ensure sensible defaults
  
  if new_column.type != self   # should use == defined above
    change_type_sql = "ALTER TABLE #{@table_name} alter #{@name} type #{new_column.to_s}"
    #puts change_type_sql
    conn.execute_immediate(change_type_sql)
  end

  if new_column.not_null != @not_null      
    # now change the NULL status, this may make the table invalid so...
    nullFlag = new_column.not_null ? "1" : "NULL"
    update_relations_fields_sql = 
       "UPDATE rdb$relation_fields set rdb$null_flags = #{nullFlag}"\
       " where rdb$relation_name='#{@table_name.upcase}' and "\
       "rdb$field_name='#{@name.upcase}'"
    conn.execute_immediate(update_relations_fields_sql)
  end
  
  # changed default or changed type
  if (new_column.default != @default) || (new_column.type != self)
    # now the default change, which is complicated!
    defaultSource = new_column.default.nil? ? "" : ("default " << InterBaseMetaFunctions.quote(new_column.default.to_s, new_column ) )
    #puts "alter table #{@table_name} add ib$$temp type #{new_column.to_s} #{defaultSource}"
    conn.execute_immediate("alter table #{@table_name} add ib$$temp #{new_column.to_s} #{defaultSource}")
    
    # standard hack to change the default type
    begin
      sql = <<-END_SQL
          update rdb$relation_fields set
          rdb$default_source=(select rdb$default_source from rdb$relation_fields where
            rdb$field_name='IB$$TEMP' and rdb$relation_name='#{@table_name.upcase}'),
          rdb$default_value=(select rdb$default_value from rdb$relation_fields where
            rdb$field_name='IB$$TEMP' and rdb$relation_name='#{@table_name.upcase}')
          where rdb$field_name='#{@name.upcase}' and rdb$relation_name='#{@table_name.upcase}';
      END_SQL
      conn.execute_immediate(sql)
    ensure
      conn.execute_immediate("alter table #{@table_name} drop ib$$temp" )
    end
   end
end

#expects_quotingObject



567
568
569
# File 'lib/ibmeta.rb', line 567

def expects_quoting
  InterBaseColumn.expects_quoting(self)
end

#rename_column(connection, new_column_name) ⇒ Object

we should also check to see if this table has indexes which need to be dropped and re-created but the migrations user should really do that



767
768
769
770
# File 'lib/ibmeta.rb', line 767

def rename_column( connection, new_column_name )
  #puts "alter table #{@table_name} alter column #{@name} to #{new_column_name}"
  connection.execute_immediate( "alter table #{@table_name} alter column #{@name} to #{new_column_name}" )
end

#to_base_typeObject



700
701
702
# File 'lib/ibmeta.rb', line 700

def to_base_type
  InterBaseColumn.to_base_type(self.type, self.sub_type)
end

#to_sObject

This method generates a textual description for a InterBaseColumn object.



668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
# File 'lib/ibmeta.rb', line 668

def to_s
  validate  # ensure sensible defaults

  if @type == InterBaseColumn::DECIMAL or @type == InterBaseColumn::NUMERIC
        "#{@type.id2name}(#{@precision},#{@scale})"
  elsif @type == InterBaseColumn::BLOB
        "#{@type.id2name} SUB_TYPE #{@sub_type}"
  elsif @type == InterBaseColumn::CHAR or @type == InterBaseColumn::VARCHAR
        "#{@type.id2name}(#{@length})"
  elsif @type == InterBaseColumn::DOUBLE
        "DOUBLE PRECISION"
  else
    @type.id2name
  end
end

#to_sqlObject



684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
# File 'lib/ibmeta.rb', line 684

def to_sql
  sql = name + " " + to_s
  if !@default.nil?
    sql << " default "
    equote = expects_quoting
    sql << "'" if equote
    sql << @default.to_s
    sql << "'" if equote
  end
  if @not_null == true
    sql << " not null"
  end
  sql      
  # all manner of other things, we are ignoring (e.g. check constraints)
end

#validateObject



603
604
605
606
607
608
# File 'lib/ibmeta.rb', line 603

def validate
  # ensure sensible defaults are set      
  @precision = @@default_precision if @precision.nil?
  @scale = @@default_scale if @scale.nil?  
  @length = @@default_length if @length.nil?
end

#validate_default_source(default_source) ⇒ Object



610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
# File 'lib/ibmeta.rb', line 610

def validate_default_source(default_source)
  if !default_source.nil?
    #puts "checking default: #{default_source}"
    match = Regexp.new( '^\s*DEFAULT\s+(.*)\s*', Regexp::IGNORECASE )
    matchData = match.match(default_source.to_s)
    if matchData
      @default = matchData[1]
      
      #puts "result was #{@default} type is #{@type}"
      
      if @default
        if InterBaseColumn.expects_quoting(self)
          len = @default.size - 2
          @default = @default[1..len]
        else
          case @type
           when InterBaseColumn::BOOLEAN
             @default = "true".casecmp( @default.to_s ) == 0
           when InterBaseColumn::DECIMAL, InterBaseColumn::NUMERIC
             @default = BigDecimal.new( @default.to_s )
           when InterBaseColumn::DOUBLE, InterBaseColumn::FLOAT
             @default = @default.to_f
           when InterBaseColumn::INTEGER
             @default = @default.to_i
           when InterBaseColumn::DATE, InterBaseColumn::TIME, InterBaseColumn::TIMESTAMP
             if @default.to_s !~ /^current/i
               @default = InterBaseMetaFunctions.db_type_cast( @default, to_s )
             end
          end
        end
      end
     end
  else
    #puts "default source passed is null"
    @default = nil
  end
end