class SQLite2DBF
The main program class. Does it.
Public Class Methods
new(*args)
click to toggle source
# File lib/sqlite2dbf.rb, line 41 def initialize(*args) options = ArgParser::parse(args) @config = Configuration.instance() @config.set(options) # Object level logger. “There can only be one!” init_logger level = (@config.debug ? Logger::DEBUG : @log.level) @log.level = level @date_fields = @config.date ? @config.date : [] @time_fields = @config.time ? @config.time : [] if(@config.source) @dbf_path = nil sqlite_file = @config.source msg = File_Checking::file_check(sqlite_file, :exist, :readable) if msg @log.error(trl("ERROR! Cannot read the source-file" ) << ": " << msg) exit false end SQLite3::Database.new(sqlite_file) do |db| tables = list(db) if(@config.list) puts "\n" << trl("Tables in the database") << ":\n\t" << tables.join("\n\t") << "\n\n" exit true elsif tables.include?(@config.name) @mapping = mapping(db) else @log.error(trl("Verify table-name! %s is not found in the database!") %(@config.name)) @log.error(trl("Tables are %s") %tables.join(', ') ) exit false end # dbf_file is eather named explicitly dbf_file = @config.target if @config.target # .., derived from the table-name dbf_file = @config.out << File::Separator << @config.name if(@config.out) # .., or identical with the original sqlite-file, minus extension, plus dbf dbf_file ||= File.dirname(sqlite_file) << File::Separator << File.basename(sqlite_file, '.*') << '.dbf' msg = nil # check if dbf_file can be used if(File.exist?(dbf_file)) msg = File_Checking.file_check(dbf_file, :file, :writable) elsif(File.exist?(File.dirname(dbf_file))) msg = File_Checking.file_check(File.dirname(dbf_file), :directory, :writable) end # then do it if(!msg) @log.debug('will transform ' << sqlite_file << ' to ' << dbf_file.to_s) transform(db, dbf_file) else # or not msg = trl("ERROR! Unsuitable file") << " : %s" %msg @log.error(msg) exit false end end else log.error trl("ERROR! Source-file is a mandatory program parameter!") log.error trl("Start this program with parameter -h or --help to see the usage-message.") end end
Private Instance Methods
create_base(dbase)
click to toggle source
# File lib/sqlite2dbf.rb, line 125 def create_base(dbase) @log.debug('creating fields') @mapping.each do |field| dbase.add_field(field.name, field.type, 200, 0) end end
date(db, value)
click to toggle source
create a date-value from value
# File lib/sqlite2dbf.rb, line 133 def date(db, value) dbf_value = db.execute("select strftime('%Y-%m-%d %H:%M:%S', " << value.to_s << ", 'unixepoch')").join # ... or not. @log.warn(trl("ATTN! SQLite2DBF cannot convert the date-value %s into DBF-compatible format.") %value.to_s) if dbf_value.start_with?('-') dbf_value = db.execute("select strftime('%s', " << value.to_s << ")").join if dbf_value.start_with?('-') end
list(db)
click to toggle source
Create a list of table-names from SQLite
# File lib/sqlite2dbf.rb, line 114 def list(db) table_names = [] table_names = db.execute('select name from sqlite_master WHERE type="table"').map {|tn| tn[0]} @log.debug('sqlite contains ' << table_names.size.to_s << ' table(s): ' << table_names.join(', ')) return table_names end
mapping(db)
click to toggle source
# File lib/sqlite2dbf.rb, line 121 def mapping(db) return Mapping.new(@config, db.table_info(@config.name), db.execute('select * from ' << @config.name ) ) end
time(db, value)
click to toggle source
create a time-value from value
# File lib/sqlite2dbf.rb, line 141 def time(db, value) db.execute("select strftime('%s', " << value.to_s << ", 'unixepoch')").join end
transform(db, dbf_file)
click to toggle source
# File lib/sqlite2dbf.rb, line 145 def transform(db, dbf_file) begin tname = @config.name table_info = db.table_info(tname) content = db.execute('select * from ' << tname ) @log.debug('have content') if(:table == dbf_file) dbf_file = @dbf_path << File::Separator << tname << (content.empty? ? '_empty' : '')<< '.dbf' end @log.debug('dbf will be ' << dbf_file) dbase = SHP::DBF.create(dbf_file) create_base(dbase) content.each_with_index do |row, record_no| @log.debug('row is ' << row.to_s) row.each_with_index do |svalue, field_index| @log.debug('object is ' << @mapping[field_index].to_s) dbf_type = @mapping[field_index].type field_name = @mapping[field_index].name if(svalue && !svalue.to_s.empty? && dbf_type) svalue = date(db, svalue) if @date_fields.include?(field_name) svalue = time(db, svalue) if @time_fields.include?(field_name) @log.debug('field is ' << field_name << ', svalue is ' << svalue.to_s << ', type is ' << dbf_type.to_s) # This is Ruby. But if you do not like the verbosity # remove the magic numbers and call them text, int and float or # similar. begin case dbf_type when 0 dbase.write_string_attribute(record_no, field_index, svalue ) when 1 dbase.write_integer_attribute(record_no, field_index, svalue) when 2 dbase.write_double_attribute(record_no, field_index, svalue) else dbase.write_null_attribute(record_no, field_index) end rescue StandardError => ex @log.warn(trl("ATTN! Field %s - Cannot write value of type %s") %[field_name, dbf_type] << ': ' << ex.message ) end end end end puts trl('DONE. Bye.') rescue SQLite3::Exception => er @log.error trl("ERROR! Cannot read the source-file") << ' (' << db.filename << "): %s" %er.message << '.' end end