Class: DBGeni::Code

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

Constant Summary collapse

PACKAGE_SPEC =
'PACKAGE SPEC'
PACKAGE_BODY =
'PACKAGE BODY'
PROCEDURE =
'PROCEDURE'
FUNCTION =
'FUNCTION'
TRIGGER =
'TRIGGER'
TYPE =
'TYPE'
UNKNOWN =
'UNKNOWN'
APPLIED =
'Applied'
EXT_MAP =
{
           'pks' => PACKAGE_SPEC,
           'pkb' => PACKAGE_BODY,
           'prc' => PROCEDURE,
           'fnc' => FUNCTION,
           'trg' => TRIGGER,
           'typ' => TYPE,
           'sql' => UNKNOWN
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(directory, filename) ⇒ Code

Returns a new instance of Code.



26
27
28
29
30
31
32
# File 'lib/dbgeni/code.rb', line 26

def initialize(directory, filename)
  @directory = directory
  @filename  = filename
  @runnable_code = nil
  set_type
  set_name
end

Instance Attribute Details

#directoryObject (readonly)

Returns the value of attribute directory.



4
5
6
# File 'lib/dbgeni/code.rb', line 4

def directory
  @directory
end

#error_messagesObject (readonly)

Returns the value of attribute error_messages.



4
5
6
# File 'lib/dbgeni/code.rb', line 4

def error_messages
  @error_messages
end

#filenameObject (readonly)

Returns the value of attribute filename.



4
5
6
# File 'lib/dbgeni/code.rb', line 4

def filename
  @filename
end

#logfileObject (readonly)

Returns the value of attribute logfile.



4
5
6
# File 'lib/dbgeni/code.rb', line 4

def logfile
  @logfile
end

#nameObject (readonly)

Returns the value of attribute name.



4
5
6
# File 'lib/dbgeni/code.rb', line 4

def name
  @name
end

#typeObject (readonly)

Returns the value of attribute type.



4
5
6
# File 'lib/dbgeni/code.rb', line 4

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/dbgeni/code.rb', line 34

def ==(other)
  if @directory == other.directory && @type == other.type && @name == other.name
    true
  else
    false
  end
end

#applied?(config, connection) ⇒ Boolean

if a hash is found in the DB then it is applied.

Returns:

  • (Boolean)


69
70
71
# File 'lib/dbgeni/code.rb', line 69

def applied?(config, connection)
  db_hash(config, connection) ? true : false
end

#apply!(config, connection, force = false) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/dbgeni/code.rb', line 88

def apply!(config, connection, force=false)
  env(config, connection)
  ensure_file_exists
  if current?(config, connection) and force != true
    raise DBGeni::CodeModuleCurrent, self.to_s
  end
  migrator = DBGeni::Migrator.initialize(config, connection)
  convert_code(config)
  begin
    migrator.compile(self)
    set_applied(config,connection)
  rescue DBGeni::MigratorCouldNotConnect
    @error_messages = ""
    raise DBGeni::MigratorCouldNotConnect
  rescue DBGeni::MigrationContainsErrors
    # MYSQL (and sybase is like mysql) and Oracle procedures are handled different.
    # In Oracle if the code fails to
    # compile, it can be because missing objects are not there, but in mysql the proc
    # will compile fine if objects are missing - the only reason it seems to not compile
    # is if the syntax is bad.
    # Also, an error loading mysql proc will result in the proc not being on the DB at all.
    # Can argue either way if DBGeni should stop on code errors. As many oracle compile errors
    # could be caused by objects that have not been created yet, best for Oracle to continue,
    # but for mysql I think it is best to stop.
    if migrator.class.to_s =~ /Oracle/
      @error_messages = migrator.migration_errors
    elsif migrator.class.to_s =~ /(Mysql|Sybase)/
      @error_messages = migrator.code_errors
    end
    unless force
      raise DBGeni::CodeApplyFailed
    end
  ensure
    @logfile = migrator.logfile
    # Only set this if it has not been set in the exception handler
    @error_messages ||= migrator.code_errors
  end
end

#convert_code(config) ⇒ Object



143
144
145
# File 'lib/dbgeni/code.rb', line 143

def convert_code(config)
  @runnable_code = DBGeni::FileConverter.convert(@directory, @filename, config)
end

#current?(config, connection) ⇒ Boolean

if the DB hash equals the file hash then it is current

Returns:

  • (Boolean)


64
65
66
# File 'lib/dbgeni/code.rb', line 64

def current?(config, connection)
  hash == nil_to_s(db_hash(config, connection))
end

#db_hash(config, connection) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/dbgeni/code.rb', line 49

def db_hash(config, connection)
  results = connection.execute("select sequence_or_hash
                                from #{config.db_table}
                                where migration_name = ?
                                and   migration_type = ?", @name, @type)
  results.length == 1 ? results[0][0] : nil
end

#hashObject

“ THis line is just to fix the bad syntax highlighting in emacs!



58
59
60
61
# File 'lib/dbgeni/code.rb', line 58

def hash
  # TODO what if file is empty?
  @hash ||= Digest::SHA1.file(File.join(@directory, @filename)).hexdigest
end

#outstanding?(config, connection) ⇒ Boolean

If there is no db_hash then its outstanding.

Returns:

  • (Boolean)


74
75
76
# File 'lib/dbgeni/code.rb', line 74

def outstanding?(config, connection)
  db_hash(config, connection) ? false : true
end

#remove!(config, connection, force = false) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/dbgeni/code.rb', line 127

def remove!(config, connection, force=false)
  env(config, connection)
  ensure_file_exists
  migrator = DBGeni::Migrator.initialize(config, connection)
  begin
    migrator.remove(self)
    remove_db_record
  rescue Exception => e
    raise DBGeni::CodeRemoveFailed, e.to_s
  end
end

#runnable_codeObject



147
148
149
150
151
152
153
# File 'lib/dbgeni/code.rb', line 147

def runnable_code
  if @runnable_code
    @runnable_code
  else
    File.join(@directory, @filename)
  end
end

#set_applied(config, connection) ⇒ Object



78
79
80
81
# File 'lib/dbgeni/code.rb', line 78

def set_applied(config, connection)
  env(config, connection)
  insert_or_set_state(APPLIED)
end

#set_removed(config, connection) ⇒ Object



83
84
85
86
# File 'lib/dbgeni/code.rb', line 83

def set_removed(config, connection)
  env(config, connection)
  remove_db_record
end

#sort_fieldObject



42
43
44
45
46
47
# File 'lib/dbgeni/code.rb', line 42

def sort_field
  # Normally alphabetical sorting is enough, but this means pkg specs sort after
  # bodies. So need to do something about that. The simplest *hack* is to replace
  # pks with pka to get it to sort before pkb, just for sorting purposes
  sortable = @filename.gsub(/\.pks$/, '.pka')
end

#to_sObject



139
140
141
# File 'lib/dbgeni/code.rb', line 139

def to_s
  "#{@type.ljust(12)} #{@name}"
end