Class: Flydata::SyncFileManager
- Inherits:
-
Object
- Object
- Flydata::SyncFileManager
- Defined in:
- lib/flydata/sync_file_manager.rb
Constant Summary collapse
- DUMP_DIR =
ENV['FLYDATA_DUMP'] || File.join(FLYDATA_HOME, 'dump')
- BACKUP_DIR =
ENV['FLYDATA_BACKUP'] || File.join(FLYDATA_HOME, 'backup')
- TABLE_POSITIONS_DIR =
ENV['FLYDATA_TABLE_POSITIONS'] || File.join(FLYDATA_HOME, 'positions')
- SYNC_TABLE_POSITIONS =
0
- SOURCE_TABLE_EXT =
"mysql_table"
Instance Method Summary collapse
- #backup_dir ⇒ Object
- #backup_dump_dir ⇒ Object
- #close ⇒ Object
- #delete_dump_file ⇒ Object
- #delete_dump_files ⇒ Object
- #delete_master_position_files ⇒ Object
- #delete_table_control_files(*tables) ⇒ Object
- #delete_table_source_pos(table_name) ⇒ Object
- #dump_file_path ⇒ Object
-
#dump_pos_path ⇒ Object
dump pos file for resume.
- #get_new_table_list(tables, file_type) ⇒ Object
- #get_table_position(table_name) ⇒ Object
- #get_table_source_pos(table_name) ⇒ Object
- #get_table_source_pos_init(table_name) ⇒ Object
-
#get_table_source_raw_pos(table_name) ⇒ Object
returns String.
-
#increment_and_save_table_position(table_name) {|seq| ... } ⇒ Object
Read a sequence number from the table’s position file, increment the number and pass the number to a block.
- #increment_table_rev(table_name, base_rev) ⇒ Object
-
#initialize(data_entry, source = nil) ⇒ SyncFileManager
constructor
A new instance of SyncFileManager.
- #install_table_source_pos_files(tables) ⇒ Object
- #load_dump_pos ⇒ Object
- #load_generated_ddl(tables) ⇒ Object
- #load_sent_source_pos(file_path = sent_source_pos_path) ⇒ Object
- #load_source_pos(file_path = source_pos_path) ⇒ Object
- #load_stats ⇒ Object
- #load_sync_info ⇒ Object
- #lock_pid_file ⇒ Object
-
#reset_table_position_files(tables) ⇒ Object
table files.
- #save_dump_pos(status, table_name, last_pos, source_pos, state = nil, substate = nil) ⇒ Object
- #save_generated_ddl(tables, contents = "1") ⇒ Object
- #save_record_count_stat(table, record_count) ⇒ Object
-
#save_sent_source_pos(source_pos) ⇒ Object
sent source pos file (binlog.pos).
-
#save_source_pos(source_pos) ⇒ Object
master binlog.pos file.
- #save_source_table_marshal_dump(source_table) ⇒ Object
- #save_ssl_ca(ssl_ca_content, path = ssl_ca_path) ⇒ Object
- #save_ssl_cipher(ssl_cipher_content, path = ssl_cipher_path) ⇒ Object
- #save_sync_info(initial_sync, tables) ⇒ Object
- #save_table_position(table_name, seq) ⇒ Object
- #save_table_source_pos(tables, source_pos, options = {}) ⇒ Object
- #sent_source_pos_path(master_source_pos_path = source_pos_path) ⇒ Object
- #source ⇒ Object
- #source_pos_path ⇒ Object
-
#source_table_marshal_dump_path ⇒ Object
SourceTable marshal file.
-
#ssl_ca_path(master_source_pos_path = source_pos_path) ⇒ Object
ssl_ca file path.
-
#ssl_cipher_path(master_source_pos_path = source_pos_path) ⇒ Object
ssl_cipher file path.
- #stats_path ⇒ Object
- #sync_info_file ⇒ Object
- #table_ddl_file_paths(*tables) ⇒ Object
- #table_position_file_paths(*tables) ⇒ Object
- #table_positions_dir_path ⇒ Object
- #table_rev(table_name) ⇒ Object
- #table_rev_file_path(table_name) ⇒ Object
- #table_rev_file_paths(*tables) ⇒ Object
- #table_source_pos_init_paths(*tables) ⇒ Object
- #table_source_pos_paths(*tables) ⇒ Object
- #tables_from_positions_dir ⇒ Object
Constructor Details
#initialize(data_entry, source = nil) ⇒ SyncFileManager
Returns a new instance of SyncFileManager.
15 16 17 18 19 20 |
# File 'lib/flydata/sync_file_manager.rb', line 15 def initialize(data_entry, source = nil) @data_entry = data_entry @source = source #for Source dependent objects @table_position_files = {} # File objects keyed by table name @sync_table_positions_count = SYNC_TABLE_POSITIONS end |
Instance Method Details
#backup_dir ⇒ Object
441 442 443 |
# File 'lib/flydata/sync_file_manager.rb', line 441 def backup_dir BACKUP_DIR end |
#backup_dump_dir ⇒ Object
431 432 433 434 435 436 437 438 439 |
# File 'lib/flydata/sync_file_manager.rb', line 431 def backup_dump_dir backup_dir = BACKUP_DIR.dup FileUtils.mkdir_p(backup_dir) unless Dir.exists?(backup_dir) dest_dir = File.join(backup_dir, Time.now.strftime("%Y%m%d%H%M%S")) FileUtils.mkdir(dest_dir) ['info', 'pos', 'stats', SOURCE_TABLE_EXT].each do |ext| FileUtils.mv(Dir.glob("#{dump_dir}/*.#{ext}"), dest_dir) end end |
#close ⇒ Object
26 27 28 29 |
# File 'lib/flydata/sync_file_manager.rb', line 26 def close @table_position_files.values.each {|f| f.close } @table_position_files = {} end |
#delete_dump_file ⇒ Object
427 428 429 |
# File 'lib/flydata/sync_file_manager.rb', line 427 def delete_dump_file FileUtils.rm(dump_file_path) if File.exists?(dump_file_path) end |
#delete_dump_files ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/flydata/sync_file_manager.rb', line 346 def delete_dump_files files_to_delete = [ dump_file_path, dump_pos_path, source_table_marshal_dump_path, sync_info_file, stats_path ] files_to_delete.flatten.each do |file_to_delete| FileUtils.rm(file_to_delete) if File.exists?(file_to_delete) end end |
#delete_master_position_files ⇒ Object
359 360 361 362 363 364 365 366 367 368 |
# File 'lib/flydata/sync_file_manager.rb', line 359 def delete_master_position_files files_to_delete = [ source_pos_path, sent_source_pos_path, lock_pid_file, ] files_to_delete.flatten.each do |file_to_delete| FileUtils.rm(file_to_delete) if File.exists?(file_to_delete) end end |
#delete_table_control_files(*tables) ⇒ Object
322 323 324 325 326 327 328 329 330 331 332 333 |
# File 'lib/flydata/sync_file_manager.rb', line 322 def delete_table_control_files(*tables) files_to_delete = [ table_position_file_paths(*tables), table_source_pos_paths(*tables), table_source_pos_init_paths(*tables), table_rev_file_paths(*tables), table_ddl_file_paths(*tables) ] files_to_delete.flatten.each do |path| FileUtils.rm(path) if File.exists?(path) end end |
#delete_table_source_pos(table_name) ⇒ Object
371 372 373 374 375 376 377 378 |
# File 'lib/flydata/sync_file_manager.rb', line 371 def delete_table_source_pos(table_name) file = File.join(table_positions_dir_path, table_name + ".binlog.pos") if File.exists?(file) FileUtils.rm(file, :force => true) else puts "#{file} does not exist. Something is wrong. Did you delete the file manually when flydata was running?" end end |
#dump_file_path ⇒ Object
31 32 33 |
# File 'lib/flydata/sync_file_manager.rb', line 31 def dump_file_path File.join(dump_dir, @data_entry['name']) + ".dump" end |
#dump_pos_path ⇒ Object
dump pos file for resume
36 37 38 |
# File 'lib/flydata/sync_file_manager.rb', line 36 def dump_pos_path dump_file_path + ".pos" end |
#get_new_table_list(tables, file_type) ⇒ Object
79 80 81 82 83 84 85 86 |
# File 'lib/flydata/sync_file_manager.rb', line 79 def get_new_table_list(tables, file_type) table_positions_dir_path = ENV['FLYDATA_TABLE_POSITIONS'] || File.join(FLYDATA_HOME, 'positions') new_tables = [] tables.each do |table| new_tables << table unless File.exists?(File.join(table_positions_dir_path, "#{table}.#{file_type}")) end new_tables end |
#get_table_position(table_name) ⇒ Object
256 257 258 259 260 261 |
# File 'lib/flydata/sync_file_manager.rb', line 256 def get_table_position(table_name) file = File.join(table_positions_dir_path, table_name + ".pos") return nil unless File.exists?(file) File.open(file) {|f| f.read} end |
#get_table_source_pos(table_name) ⇒ Object
396 397 398 399 400 401 |
# File 'lib/flydata/sync_file_manager.rb', line 396 def get_table_source_pos(table_name) source_pos_str = get_table_source_raw_pos(table_name) return nil unless source_pos_str source.source_pos.create_source_pos( source_pos_str ) end |
#get_table_source_pos_init(table_name) ⇒ Object
284 285 286 287 288 289 |
# File 'lib/flydata/sync_file_manager.rb', line 284 def get_table_source_pos_init(table_name) file = File.join(table_positions_dir_path, table_name + ".binlog.pos.init") return nil unless File.exists?(file) source.source_pos.create_source_pos( File.open(file, 'r').readline ) end |
#get_table_source_raw_pos(table_name) ⇒ Object
returns String. interface for fluentd
403 404 405 406 407 408 |
# File 'lib/flydata/sync_file_manager.rb', line 403 def get_table_source_raw_pos(table_name) #returns String. interface for fluentd file = File.join(table_positions_dir_path, table_name + ".binlog.pos") return nil unless File.exists?(file) File.open(file, 'r').readline end |
#increment_and_save_table_position(table_name) {|seq| ... } ⇒ Object
Read a sequence number from the table’s position file, increment the number and pass the number to a block. After executing the block, saves the value to the position file.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/flydata/sync_file_manager.rb', line 212 def increment_and_save_table_position(table_name) file = File.join(table_positions_dir_path, table_name + ".pos") retry_count = 0 begin @table_position_files[table_name] ||= (f = File.open(file, File::RDWR); f.sync = true; f) rescue Errno::ENOENT raise if retry_count > 0 # Already retried. Must be a differentfile causing the error # File not exist. Create one with initial value of '0' File.open(file, "w") {|f| f.write('0') } retry_count += 1 retry end f = @table_position_files[table_name] seq = f.read prev_seq_len = seq.size f.rewind seq = seq.to_i + 1 seq = FlydataCore::QueryJob::SYNC_FIRST_SEQ if seq == 1 new_seq_len = seq.to_s.size seq_to_write = seq.to_s if new_seq_len < prev_seq_len seq_to_write += " " * (prev_seq_len - new_seq_len) end # logical transaction starts yield(seq) f.write(seq_to_write) if @sync_table_positions_count > 1 @sync_table_positions_count -= 1 elsif @sync_table_positions_count == 1 f.fsync @sync_table_positions_count = SYNC_TABLE_POSITIONS end # logical transaction ends f.truncate(new_seq_len) if new_seq_len < prev_seq_len f.rewind end |
#increment_table_rev(table_name, base_rev) ⇒ Object
313 314 315 316 317 318 319 320 |
# File 'lib/flydata/sync_file_manager.rb', line 313 def increment_table_rev(table_name, base_rev) file = table_rev_file_path(table_name) new_rev = base_rev + 1 File.open(file, "w") do |f| f.write(new_rev) end new_rev end |
#install_table_source_pos_files(tables) ⇒ Object
412 413 414 415 416 417 418 419 420 421 422 423 424 425 |
# File 'lib/flydata/sync_file_manager.rb', line 412 def install_table_source_pos_files(tables) FileUtils.mkdir_p(table_positions_dir_path) unless Dir.exists?(table_positions_dir_path) tables.each do |table_name| file_name = table_name + ".binlog.pos" src_file = File.join(dump_dir, file_name) if ! File.exists?(src_file) raise "#{src_file} does not exist. Error!!" end FileUtils.mv(src_file, table_positions_dir_path) # save the position at initial sync. this is used for repair if # necessary. FileUtils.cp(File.join(table_positions_dir_path, file_name), File.join(table_positions_dir_path, file_name + ".init")) end end |
#load_dump_pos ⇒ Object
46 47 48 49 50 51 52 53 |
# File 'lib/flydata/sync_file_manager.rb', line 46 def load_dump_pos path = dump_pos_path return {} unless File.exists?(path) content = File.open(path, 'r').readline source_table = load_source_table_marshal_dump dump_pos_content_to_hash(content).merge( { source_table: source_table} ) end |
#load_generated_ddl(tables) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/flydata/sync_file_manager.rb', line 55 def load_generated_ddl(tables) tables = [ tables ] unless tables.kind_of?(Array) paths = table_ddl_file_paths(*tables) paths.collect{|path| begin File.open(path) {|f| f.read } rescue Errno::ENOENT nil end } end |
#load_sent_source_pos(file_path = sent_source_pos_path) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/flydata/sync_file_manager.rb', line 133 def load_sent_source_pos(file_path = sent_source_pos_path) return nil unless File.exists?(file_path) source_pos_str = IO.read(file_path).strip begin source_pos = source.source_pos.create_source_pos(source_pos_str) rescue RuntimeError return nil end source_pos end |
#load_source_pos(file_path = source_pos_path) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/flydata/sync_file_manager.rb', line 109 def load_source_pos(file_path = source_pos_path) return nil unless File.exists?(file_path) source_pos_str = IO.read(file_path).strip begin context = source.source_pos source_pos = context.create_source_pos(source_pos_str) rescue RuntimeError return nil end source_pos end |
#load_stats ⇒ Object
455 456 457 458 |
# File 'lib/flydata/sync_file_manager.rb', line 455 def load_stats return nil unless File.exists?(stats_path) Hash[*File.read(stats_path).split(/\t/)] end |
#load_sync_info ⇒ Object
277 278 279 280 281 282 |
# File 'lib/flydata/sync_file_manager.rb', line 277 def load_sync_info return nil unless File.exists?(sync_info_file) items = File.open(sync_info_file, 'r').readline.split("\t") { initial_sync: (items[0] == 'true'), tables: items[1].split(" ") } end |
#lock_pid_file ⇒ Object
263 264 265 |
# File 'lib/flydata/sync_file_manager.rb', line 263 def lock_pid_file FLYDATA_LOCK end |
#reset_table_position_files(tables) ⇒ Object
table files
177 178 179 180 181 182 |
# File 'lib/flydata/sync_file_manager.rb', line 177 def reset_table_position_files(tables) tables.each do |table_name| file = File.join(table_positions_dir_path, table_name + ".pos") File.open(file, "w") {|f| f.write('0') } end end |
#save_dump_pos(status, table_name, last_pos, source_pos, state = nil, substate = nil) ⇒ Object
40 41 42 43 44 |
# File 'lib/flydata/sync_file_manager.rb', line 40 def save_dump_pos(status, table_name, last_pos, source_pos, state = nil, substate = nil) File.open(dump_pos_path, 'w') do |f| f.write(dump_pos_content(status, table_name, last_pos, source_pos, state, substate)) end end |
#save_generated_ddl(tables, contents = "1") ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/flydata/sync_file_manager.rb', line 67 def save_generated_ddl(tables, contents = "1") tables = [ tables ] unless tables.kind_of?(Array) table_positions_dir_path = ENV['FLYDATA_TABLE_POSITIONS'] || File.join(FLYDATA_HOME, 'positions') #Create positions if dir does not exist unless File.directory?(table_positions_dir_path) FileUtils.mkdir_p(table_positions_dir_path) end tables.each do |tab| File.open(File.join(table_positions_dir_path, "#{tab}.generated_ddl"), 'w') {|f| f.write(contents) } end end |
#save_record_count_stat(table, record_count) ⇒ Object
449 450 451 452 453 |
# File 'lib/flydata/sync_file_manager.rb', line 449 def save_record_count_stat(table, record_count) stats = load_stats || Hash.new stats[table] = stats[table] ? stats[table].to_i + record_count : record_count save_stats(stats) end |
#save_sent_source_pos(source_pos) ⇒ Object
sent source pos file (binlog.pos)
127 128 129 130 131 |
# File 'lib/flydata/sync_file_manager.rb', line 127 def save_sent_source_pos(source_pos) File.open(sent_source_pos_path, 'w') do |f| f.write(source_pos.to_s) end end |
#save_source_pos(source_pos) ⇒ Object
master binlog.pos file
102 103 104 105 106 107 |
# File 'lib/flydata/sync_file_manager.rb', line 102 def save_source_pos(source_pos) path = source_pos_path File.open(path, 'w') do |f| f.write(source_pos.to_s) end end |
#save_source_table_marshal_dump(source_table) ⇒ Object
95 96 97 98 99 |
# File 'lib/flydata/sync_file_manager.rb', line 95 def save_source_table_marshal_dump(source_table) File.open(source_table_marshal_dump_path, 'w') do |f| f.write Marshal.dump(source_table) end end |
#save_ssl_ca(ssl_ca_content, path = ssl_ca_path) ⇒ Object
157 158 159 160 161 |
# File 'lib/flydata/sync_file_manager.rb', line 157 def save_ssl_ca(ssl_ca_content, path = ssl_ca_path) File.open(path, 'w') do |f| f.write(ssl_ca_content) end end |
#save_ssl_cipher(ssl_cipher_content, path = ssl_cipher_path) ⇒ Object
170 171 172 173 174 |
# File 'lib/flydata/sync_file_manager.rb', line 170 def save_ssl_cipher(ssl_cipher_content, path = ssl_cipher_path) File.open(path, 'w') do |f| f.write(ssl_cipher_content) end end |
#save_sync_info(initial_sync, tables) ⇒ Object
271 272 273 274 275 |
# File 'lib/flydata/sync_file_manager.rb', line 271 def save_sync_info(initial_sync, tables) File.open(sync_info_file, "w") do |f| f.write([initial_sync, tables.join(" ")].join("\t")) end end |
#save_table_position(table_name, seq) ⇒ Object
250 251 252 253 254 |
# File 'lib/flydata/sync_file_manager.rb', line 250 def save_table_position(table_name, seq) file = File.join(table_positions_dir_path, table_name + ".pos") File.open(file, "w") {|f| f.write(seq)} end |
#save_table_source_pos(tables, source_pos, options = {}) ⇒ Object
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/flydata/sync_file_manager.rb', line 380 def save_table_source_pos(tables, source_pos, = {}) dest_dir = case [:destination] when :positions; table_positions_dir_path when :dump; dump_dir else dump_dir end tables = [ tables ] unless tables.kind_of?(Array) tables.each do |table_name| file = File.join(dest_dir, table_name + ".binlog.pos") File.open(file, "w") do |f| f.write(source_pos.to_s) end end end |
#sent_source_pos_path(master_source_pos_path = source_pos_path) ⇒ Object
145 146 147 148 |
# File 'lib/flydata/sync_file_manager.rb', line 145 def sent_source_pos_path(master_source_pos_path = source_pos_path) validate_master_source_pos_path(master_source_pos_path) "#{master_source_pos_path[0..-5]}.sent.pos" end |
#source ⇒ Object
22 23 24 |
# File 'lib/flydata/sync_file_manager.rb', line 22 def source @source end |
#source_pos_path ⇒ Object
122 123 124 |
# File 'lib/flydata/sync_file_manager.rb', line 122 def source_pos_path File.join(FLYDATA_HOME, @data_entry['name'] + ".binlog.pos") end |
#source_table_marshal_dump_path ⇒ Object
SourceTable marshal file
91 92 93 |
# File 'lib/flydata/sync_file_manager.rb', line 91 def source_table_marshal_dump_path dump_file_path + ".#{SOURCE_TABLE_EXT}" end |
#ssl_ca_path(master_source_pos_path = source_pos_path) ⇒ Object
ssl_ca file path
151 152 153 154 155 |
# File 'lib/flydata/sync_file_manager.rb', line 151 def ssl_ca_path(master_source_pos_path = source_pos_path) validate_master_source_pos_path(master_source_pos_path) # <data-entry-name>.ssl_ca.pem "#{master_source_pos_path[0..-12]}.ssl_ca.pem" end |
#ssl_cipher_path(master_source_pos_path = source_pos_path) ⇒ Object
ssl_cipher file path
164 165 166 167 168 |
# File 'lib/flydata/sync_file_manager.rb', line 164 def ssl_cipher_path(master_source_pos_path = source_pos_path) validate_master_source_pos_path(master_source_pos_path) # <data-entry-name>.ssl_cipher "#{master_source_pos_path[0..-12]}.ssl_cipher" end |
#stats_path ⇒ Object
445 446 447 |
# File 'lib/flydata/sync_file_manager.rb', line 445 def stats_path File.join(dump_dir, @data_entry['name']) + ".stats" end |
#sync_info_file ⇒ Object
267 268 269 |
# File 'lib/flydata/sync_file_manager.rb', line 267 def sync_info_file File.join(dump_dir, "sync.info") end |
#table_ddl_file_paths(*tables) ⇒ Object
193 194 195 196 |
# File 'lib/flydata/sync_file_manager.rb', line 193 def table_ddl_file_paths(*tables) tables.empty? ? Dir.glob(File.join(table_positions_dir_path, '*.generated_ddl')) : tables.map{|table| File.join(table_positions_dir_path, table + '.generated_ddl')} end |
#table_position_file_paths(*tables) ⇒ Object
188 189 190 191 |
# File 'lib/flydata/sync_file_manager.rb', line 188 def table_position_file_paths(*tables) tables.empty? ? Dir.glob(File.join(table_positions_dir_path, '*.pos')) : tables.map{|table| File.join(table_positions_dir_path, table + '.pos')} end |
#table_positions_dir_path ⇒ Object
184 185 186 |
# File 'lib/flydata/sync_file_manager.rb', line 184 def table_positions_dir_path TABLE_POSITIONS_DIR end |
#table_rev(table_name) ⇒ Object
300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/flydata/sync_file_manager.rb', line 300 def table_rev(table_name) file = table_rev_file_path(table_name) return 1 unless File.exists?(file) #default revision is 1 File.open(file, "r+") do |f| seq = f.read if seq.empty? return 1 else return seq.to_i end end end |
#table_rev_file_path(table_name) ⇒ Object
291 292 293 |
# File 'lib/flydata/sync_file_manager.rb', line 291 def table_rev_file_path(table_name) File.join(table_positions_dir_path, table_name + ".rev") end |
#table_rev_file_paths(*tables) ⇒ Object
295 296 297 298 |
# File 'lib/flydata/sync_file_manager.rb', line 295 def table_rev_file_paths(*tables) tables.empty? ? Dir.glob(File.join(table_positions_dir_path, "*.rev")) : tables.map{|table| table_rev_file_path(table)} end |
#table_source_pos_init_paths(*tables) ⇒ Object
203 204 205 206 |
# File 'lib/flydata/sync_file_manager.rb', line 203 def table_source_pos_init_paths(*tables) tables.empty? ? Dir.glob(File.join(table_positions_dir_path, '*.binlog.pos.init')) : tables.map{|table| File.join(table_positions_dir_path, table + '.binlog.pos.init')} end |
#table_source_pos_paths(*tables) ⇒ Object
198 199 200 201 |
# File 'lib/flydata/sync_file_manager.rb', line 198 def table_source_pos_paths(*tables) tables.empty? ? Dir.glob(File.join(table_positions_dir_path, '*.binlog.pos')) : tables.map{|table| File.join(table_positions_dir_path, table + '.binlog.pos')} end |
#tables_from_positions_dir ⇒ Object
335 336 337 338 339 340 341 342 343 344 |
# File 'lib/flydata/sync_file_manager.rb', line 335 def tables_from_positions_dir all_table_control_files = Dir.glob(File.join(table_positions_dir_path, '*.{pos,generated_ddl,init,rev}')) tables = Set.new all_table_control_files.each do |control_file| file_name = File.basename(control_file) file_name = file_name.slice(0...(file_name.index('.'))) tables << file_name end tables.to_a end |