Class: Migr8::Repository

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

Constant Summary collapse

HISTORY_FILEPATH =
'migr8/history.txt'
HISTORY_TABLE =
'_migr8_history'
MIGRATION_DIRPATH =
'migr8/migrations/'
VERSION_CHARS =
('a'..'z').to_a - ['l']
VERSION_DIGITS =
('0'..'9').to_a - ['1']

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dbms = nil) ⇒ Repository

Returns a new instance of Repository.



136
137
138
# File 'lib/migr8.rb', line 136

def initialize(dbms=nil)
  @dbms = dbms
end

Instance Attribute Details

#dbmsObject (readonly)

Returns the value of attribute dbms.



134
135
136
# File 'lib/migr8.rb', line 134

def dbms
  @dbms
end

Instance Method Details

#_new_versionObject



239
240
241
242
243
244
245
246
247
248
# File 'lib/migr8.rb', line 239

def _new_version
  version = ''
  s = VERSION_CHARS
  n = s.length - 1
  4.times { version << s[rand(n)] }
  d = VERSION_DIGITS
  n = d.length - 1
  4.times { version << d[rand(n)] }
  return version
end

#apply_migrations(migs) ⇒ Object



215
216
217
# File 'lib/migr8.rb', line 215

def apply_migrations(migs)
  @dbms.apply_migrations(migs)
end

#create_migration(version = nil, author = nil, desc = "", opts = {}) ⇒ Object



303
304
305
306
307
308
309
310
311
312
# File 'lib/migr8.rb', line 303

def create_migration(version=nil, author=nil, desc="", opts={})
  if version && migration_file_exist?(version)
    raise MigrationError.new("#{version}: migration file already exists.")
  end
  mig = Migration.new(version || new_version(), author || Etc.getlogin(), desc)
  content = render_migration_file(mig, opts)
  File.open(mig.filepath, 'wb') {|f| f.write(content) }
  File.open(history_filepath(), 'ab') {|f| f.write(to_line(mig)) }
  return mig
end

#delete_migration(version) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/migr8.rb', line 314

def delete_migration(version)
  mig = load_migration(version)  or
    raise MigrationError.new("#{version}: migration not found.")
  fetch_details_from_history_table(mig)
  ! mig.applied?  or
    raise MigrationError.new("#{version}: already applied.
Please run `#{File.basename($0)} unapply #{version}` at first if you want to delete it.")
  #
  File.open(history_filepath(), 'r+') do |f|
    content = f.read()
    content.gsub!(/^#{version}\b.*\n/, '')
    f.rewind()
    f.truncate(0)
    f.write(content)
  end
  File.unlink(migration_filepath(version))
  return mig
end

#fetch_details_from_history_table(mig) ⇒ Object



223
224
225
226
227
228
229
# File 'lib/migr8.rb', line 223

def fetch_details_from_history_table(mig)
  s = @dbms.fetch_column_value_of(mig.version, 'applied_at')
  s = s.strip if s
  mig.applied_at  = (s.nil? || s.empty? ? nil : s)
  mig.up_script   = @dbms.fetch_column_value_of(mig.version, 'up_script')
  mig.down_script = @dbms.fetch_column_value_of(mig.version, 'down_script')
end

#history_file_empty?Boolean

Returns:

  • (Boolean)


290
291
292
293
294
295
296
297
# File 'lib/migr8.rb', line 290

def history_file_empty?
  fpath = history_filepath()
  return true unless File.file?(fpath)
  exist_p = File.open(fpath, 'rb') {|f|
    f.any? {|line| line =~ /\A\s*\w+/ }
  }
  return ! exist_p
end

#history_file_exist?Boolean

Returns:

  • (Boolean)


285
286
287
288
# File 'lib/migr8.rb', line 285

def history_file_exist?
  fpath = history_filepath()
  return File.file?(fpath)
end

#history_filepathObject



140
141
142
# File 'lib/migr8.rb', line 140

def history_filepath()
  return HISTORY_FILEPATH
end

#initObject



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/migr8.rb', line 253

def init()
  verbose = true
  ## create directory
  path = migration_filepath('_dummy_')
  dirs = []
  while ! (path = File.dirname(path)).empty? && path != '.' && path != '/'
    dirs << path
  end
  dirs.reverse_each do |dir|
    if ! File.directory?(dir)
      puts "$ mkdir #{dir}" if verbose
      Dir.mkdir(dir)
    end
  end
  ## create history file
  fpath = history_filepath()
  if ! File.file?(fpath)
    magic = '# -*- coding: utf-8 -*-'
    puts "$ echo '#{magic}' > #{fpath}" if verbose
    File.open(fpath, 'w') {|f| f.write(magic+"\n") }
  end
  ## create history table
  @dbms.create_history_table()
end

#init?Boolean

Returns:

  • (Boolean)


278
279
280
281
282
283
# File 'lib/migr8.rb', line 278

def init?
  return false unless File.file?(history_filepath())
  return false unless File.directory?(File.dirname(migration_filepath('_')))
  return false unless @dbms.history_table_exist?
  return true
end

#load_migration(version) ⇒ Object



209
210
211
212
213
# File 'lib/migr8.rb', line 209

def load_migration(version)
  fpath = migration_filepath(version)
  return nil unless File.file?(fpath)
  return Migration.load_from(fpath)
end

#migration_file_exist?(version) ⇒ Boolean

Returns:

  • (Boolean)


299
300
301
# File 'lib/migr8.rb', line 299

def migration_file_exist?(version)
  return File.exist?(migration_filepath(version))
end

#migration_filepath(version) ⇒ Object



144
145
146
# File 'lib/migr8.rb', line 144

def migration_filepath(version)
  return "#{MIGRATION_DIRPATH}#{version}.yaml"
end

#migrations_in_history_file(applied_migrations_dict = nil) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/migr8.rb', line 183

def migrations_in_history_file(applied_migrations_dict=nil)
  dict = applied_migrations_dict  # {version=>applied_at}
  applied = nil
  tuples = parse_history_file()
  fpath = history_filepath()
  migrations = tuples.collect {|version, author, desc|
    mig = load_migration(version)  or
      raise HistoryFileError.new("#{version}: migration file not found (please edit history file by 'migr8.rb hist -o' and delete or comment out it).")
    mig.version == version  or
      raise MigrationError.new("#{version}: version in migration file (='mig.filepath') should be '#{version}' but got #{mig.version}.
Please run '#{File.basename($0)} edit #{version}' and fix version in that file.")
      #$stderr << "# WARNING: #{version}: version in history file is not match to #{fpath}\n"
    mig.author == author  or
      $stderr << "# WARNING: #{version}: author in history file is not match to #{fpath}\n"
    mig.desc == desc  or
      $stderr << "# WARNING: #{version}: description in history file is not match to #{fpath}\n"
    mig.applied_at = applied.applied_at if dict && (applied = dict.delete(mig.version))
    mig
  }
  return migrations
end

#migrations_in_history_tableObject



205
206
207
# File 'lib/migr8.rb', line 205

def migrations_in_history_table()
  return @dbms.get_migrations()
end

#new_versionObject



231
232
233
234
235
236
237
# File 'lib/migr8.rb', line 231

def new_version
  while true
    version = _new_version()
    break unless File.file?(migration_filepath(version))
  end
  return version
end

#parse_history_fileObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/migr8.rb', line 148

def parse_history_file()
  fpath = history_filepath()
  tuples = []
  eol = nil
  File.open(fpath) do |f|
    i = 0
    f.each do |line|
      i += 1
      eol = line[-1]
      line.strip!
      next if line =~ /\A\#/
      next if line.empty?
      line =~ /\A([-\w]+)[ \t]*\# \[(.*)\][ \t]*(.*)\z/  or
        raise HistoryFileError.new("File '#{fpath}', line #{i}: invalid format.\n    #{line}")
      version, author, desc = $1, $2, $3
      tuples << [version, author, desc]
    end
  end
  eol == ?\n  or
    raise HistoryFileError.new("missing newline character (\"\\n\") at end of history file.
Plese open it by `migr8.rb hist -o` and add newline character at end of file.")
  return tuples
end

#rebuild_history_fileObject



172
173
174
175
176
177
178
179
180
181
# File 'lib/migr8.rb', line 172

def rebuild_history_file()
  tuples = parse_history_file()
  s = "# -*- coding: utf-8 -*-\n"
  tuples.each do |version, author, desc|
    s << _to_line(version, author, desc)
  end
  fpath = history_filepath()
  File.open(fpath, 'w') {|f| f.write(s) }
  return s
end

#unapply_migrations(migs, down_script_in_db = false) ⇒ Object



219
220
221
# File 'lib/migr8.rb', line 219

def unapply_migrations(migs, down_script_in_db=false)
  @dbms.unapply_migrations(migs, down_script_in_db)
end