sqlite2dbf 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45babe3b6624235add48f6c62c22a5aaccefc294
4
+ data.tar.gz: bd7ed59177cb0fa945defa4e0413558bcdd5823b
5
+ SHA512:
6
+ metadata.gz: c7920489b4c73e5f1799c8cf5a695ad97cd30dfe294b68cf377d9e02e53df306277223197b3fc5a1b8c77008e6dea5140163b87f71cc9c4438f323f58816ce99
7
+ data.tar.gz: 2dccbcbd83841acb53670181820f58f9cb1df999437f89d492894384a3a52a3dc5b64780097abddb0a4163100f6e1a612a3af7ad4247d8588d79036350397cc3
data/bin/sqlite2dbf ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * ©2011-2013, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+
24
+ require_relative '../lib/sqlite2dbf'
25
+ SQLite2DBF.new(*ARGV)
data/lib/argparser.rb ADDED
@@ -0,0 +1,113 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+ =end
22
+
23
+
24
+ require 'optparse'
25
+ require 'optparse/time'
26
+ require 'ostruct'
27
+ require_relative 'logging'
28
+ require_relative 'translating'
29
+ require_relative 'constants'
30
+
31
+ class ArgParser
32
+ include Logging
33
+ include Translating
34
+
35
+ self.extend(Logging)
36
+ self.extend(Translating)
37
+ @@log = init_logger()
38
+
39
+ # Returns a structure describing the options.
40
+ #
41
+ def self.parse(args)
42
+ # The options specified on the command line will be collected in <b>options</b>.
43
+ # We set default values here.
44
+ options = OpenStruct.new
45
+ options.debug = false
46
+
47
+ op = OptionParser.new do |opts|
48
+ opts.banner = "\n" << trl("Usage") << ":\t" << $APPNAME.dup << ' ' << trl("-s [sqlite-file] [options]") << "\n\t" << trl("or %s [Common options]") %($APPNAME)
49
+
50
+ opts.separator ""
51
+ opts.separator trl("Specific options") << ':'
52
+ opts.on('-' << trl("s"), '--' << trl("source/sqlite-file [FILE.sqlite]"), trl( "SQLite-file to read.")) do |source|
53
+ options.source = source
54
+ end
55
+ opts.on('-' << trl("t"), '--' << trl("dBase-files [FILE(0...n).dbf]"), trl( "Name for the dBase-files (1 per table) to be written.")) do |target|
56
+ options.target = target
57
+ end
58
+
59
+ opts.on('-' << trl('o'), trl("--orig"), trl('Use the table-name as file-name for the DBF-result')) do
60
+ options.table_name = true
61
+ end
62
+
63
+ =begin
64
+
65
+ # This is for later. The evaluation of the file-content may be allocated to the
66
+ # Configuration singleton, as it does not mean a lot of I/O nor does it imply
67
+ # much management.
68
+
69
+ opts.on("-c", "--config [CONFIG FILE]",
70
+ "Read alternative configuration from this file") do |conf|
71
+ $LOG.debug("config-file should be #{conf}") if $LOG
72
+ options.config = File.expand_path(conf )
73
+ end
74
+ opts.on("-g", "--generic [CONFIG FILE]",
75
+ "Write generic configuration options to this file") do |file|
76
+ options.generic = File.expand_path(file )
77
+ end
78
+ =end
79
+ opts.separator ""
80
+ opts.separator trl("Common options") << ':'
81
+
82
+ # No argument, shows at tail. This will print an options summary.
83
+ #
84
+ opts.on_tail(trl("-d"), trl("--debug"), trl("Show debug-messages") ) do
85
+ options.debug = true
86
+ end
87
+
88
+
89
+ opts.on_tail(trl("-h"), trl("--help"), trl("Show this message") ) do
90
+ puts opts
91
+ exit true
92
+ end
93
+
94
+ opts.on_tail(trl("-v"), trl("--version"), trl("Show version and program information") ) do
95
+ puts "\t#{$APPNAME}"
96
+ puts "\t© #{$YEARS}, } <#{$AUTHORS.join(', ')}>"
97
+ exit true
98
+ end
99
+ end
100
+ begin
101
+ op.parse!(args)
102
+ rescue OptionParser::ParseError => er
103
+ msg = trl("ERROR! Unsuitable or incomplete program-arguments") << (": %s" %er.message )
104
+ puts msg
105
+ puts trl("Start this program with parameter -h or --help to see the usage-message.")
106
+ exit false
107
+ end
108
+
109
+ options
110
+ end # parse()
111
+
112
+ end
113
+
data/lib/constants.rb ADDED
@@ -0,0 +1,9 @@
1
+ $APPNAME = 'sqlite2dbf'
2
+ $VERSION = '0.1.6'
3
+ $DATE = '2016-11-12'
4
+ $AUTHORS = ["Michael Uplawski <michael.uplawski@uplawski.eu>"]
5
+ $EMAIL = 'michael.uplawski@uplawski.eu'
6
+ $LICENSE = 'GPL-3.0'
7
+
8
+ $YEARS = '2016'
9
+
@@ -0,0 +1,89 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2011-2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+ =end
22
+
23
+ =begin
24
+ A module to facilitate frequently occuring checks on
25
+ file-system objects. You can certainly do without this,
26
+ but maybe you find it useful.
27
+ =end
28
+ module File_Checking
29
+
30
+ @@text_messages = {
31
+ :exist? => "does not exist!",
32
+ :exist => "does not exist!",
33
+ :readable? => "is not readable!",
34
+ :readable => "is not readable!",
35
+ :executable? => "is not executable!",
36
+ :executable => "is not executable!",
37
+ :writable? => "is not writable!",
38
+ :writable => "is not writable!",
39
+ :directory? => "is not a directory!",
40
+ :directory => "is not a directory!",
41
+ :file? => "is not a file!",
42
+ :file => "is not a file!",
43
+ }
44
+
45
+ # Checks if the file with the name from the first
46
+ # parameter has the properties, listed in the second.
47
+ # The messages parameter is an array of one or several
48
+ # of :exist?, :readable?, :writable?, :directory? or
49
+ # their string-representations, respectively.
50
+ # Returns nil in case of success, otherwise an
51
+ # informative message, describing the first negative
52
+ # test-result.
53
+ def file_check(file, *messages)
54
+ File_Checking.file_check(file, *messages)
55
+ end
56
+
57
+ # Checks if the file with the name from the first
58
+ # parameter has the properties, listed in the second.
59
+ # The messages parameter is an array of one or all
60
+ # of :exist?, :readable?, :writable?, :directory? or
61
+ # their string-representations, respectively.
62
+ # Returns nil in case of success, otherwise an
63
+ # informative message, describing the first negative
64
+ # test-result.
65
+ def self.file_check(file, *messages)
66
+ msg = nil
67
+ if(file && messages.respond_to?(:to_ary) && !messages.empty?)
68
+ messages.each do |k|
69
+ if(! k.to_s.end_with?('?'))
70
+ k = (k.to_s << '?').to_sym
71
+ end
72
+ @log.debug ('checking ' << k.to_s) if @log
73
+ if(msg == nil && File.respond_to?(k) && ! File.send(k, file.to_s))
74
+ msg = "#{file} #{@@text_messages[k.to_sym]}"
75
+ end
76
+ end
77
+ end
78
+ msg
79
+ end
80
+ alias :check_file :file_check
81
+ end
82
+
83
+ =begin
84
+ # example
85
+
86
+ include File_Checking
87
+ msg = file_check('some_file.txt', [:exist?, :readable?, 'writable'])
88
+ puts msg if msg
89
+ =end
data/lib/log.conf ADDED
@@ -0,0 +1,53 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2013-2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+
22
+ A simplified logger configuration. Set the level for each individual logger
23
+ below. Choose a different log-device or log-file if you like. Keep the
24
+ formatting intact. Do not change other sections of this file.
25
+ =end
26
+
27
+ # Do not touch from here ----->
28
+ require 'logger'
29
+
30
+ debug = Logger::DEBUG
31
+ info = Logger::INFO
32
+ error = Logger::ERROR
33
+ fatal = Logger::FATAL
34
+ warn = Logger::WARN
35
+ unknown = Logger::UNKNOWN
36
+ {
37
+ # <---------------- to here !
38
+
39
+ # Enter your settings here, but take into consideration that not all
40
+ # the named classes will really produce readable output. Well, you can
41
+ # always try... Either name just the log-level or make the log-level
42
+ # precede the output-device or output-file like in the examples.
43
+
44
+ # Example: naming a log-file
45
+ # :HtmlBuilder => [info, 'C:\temp\htmlbuilder.log']
46
+ # :HtmlBuilder => [debug, '/tmp/htmlbuilder.log'],
47
+
48
+ :SQLite2DBF => info,
49
+
50
+ # And ignore the remainder, too.
51
+ }
52
+
53
+ #eof
data/lib/logging.rb ADDED
@@ -0,0 +1,193 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2011-2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
+ * *
6
+ * This program is free software; you can redistribute it and/or modify *
7
+ * it under the terms of the GNU General Public License as published by *
8
+ * the Free Software Foundation; either version 3 of the License, or *
9
+ * (at your option) any later version. *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
+ * GNU General Public License for more details. *
15
+ * *
16
+ * You should have received a copy of the GNU General Public License *
17
+ * along with this program; if not, write to the *
18
+ * Free Software Foundation, Inc., *
19
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20
+ ***************************************************************************/
21
+ =end
22
+ require 'logger'
23
+ require_relative 'file_checking'
24
+
25
+ =begin Creates a member @log and precede its output with the name of the class
26
+ of the object.
27
+ Example for a class-level logger:
28
+ # --------------------
29
+ class TClass
30
+ self.extend(Logging)
31
+ @@log = init_logger(STDOUT)
32
+ def test_log
33
+ @@log.info('class-level logger called from instance: ' << @@log.to_s)
34
+ @log = @@log
35
+ @log.info('AGAIN: class-level logger called from instance: ' << @log.to_s)
36
+ end
37
+ def self::test_log
38
+ @log.info('class-level logger called from class: ' << @log.to_s)
39
+ @@log.info('AGAIN: class-level logger called from class: ' << @@log.to_s)
40
+ end
41
+ end
42
+ #---------------------
43
+ Example for a object-level logger:
44
+ ATTN! This means 1 logger per object.
45
+ # --------------------
46
+ class TClass
47
+ include Logging
48
+ def initialize
49
+ init_logger(STDOUT, Logger::DEBUG)
50
+ end
51
+ def test_log
52
+ @log.debug('called test_log() ')
53
+ end
54
+ end
55
+ =end
56
+ module Logging
57
+ include File_Checking
58
+
59
+ @@have_log = false
60
+ @@LOG_CONF = File.dirname(File.absolute_path(__FILE__)) << File::Separator << 'log.conf'
61
+
62
+ # Call this method in an instance-method (e.g. initialize() ) to define the
63
+ # object-level logger; i.e. an object-specific member @log.
64
+ # Call this method within the class-definition for a class-level logger; i.e.
65
+ # a member @log for class-level acces.
66
+ # The method returns the logger, so you can actually do what you want with it.
67
+ def init_logger(target = STDOUT, level = Logger::INFO)
68
+ # Prepare for a class-level logger. This is actually quite cool.
69
+
70
+ # ---> Ingeniuous code starts here
71
+ cn = (self.class == Class ? name : self.class.name)
72
+ # <--- Ingeniuous code ends here
73
+
74
+ # allow to override the set log-levels with an
75
+ # external configuration (log.conf).
76
+ log_conf(cn)
77
+ # Or use the defaults as set here or elsewhere...
78
+
79
+ @level ||= level
80
+ @target ||= target
81
+
82
+ @log = Logger.new(@target)
83
+ @log.level = @level
84
+
85
+ @log.formatter = proc do |severity, datetime, progname, msg|
86
+ t = Time.now
87
+ "#{cn}: #{severity} #{t.hour}-#{t.min}-#{t.sec}: #{msg}\n"
88
+ end
89
+ if ! @@have_log
90
+ @log.debug cn.dup << ' reading logging-configuration from ' << @@LOG_CONF
91
+ @@have_log = true
92
+ @log.debug('level is ' << level.to_s)
93
+ end
94
+ return @log
95
+ end
96
+
97
+ # Set the log-target to an IO object.
98
+ def log_target=(target)
99
+ @target = target
100
+ @log = Logger.new(@@target)
101
+ @log.level = @level
102
+ end
103
+
104
+ # set the log-level
105
+ def log_level=(level)
106
+ @level = level
107
+ @log.level = @level
108
+ end
109
+
110
+ private
111
+
112
+ # Override or set the log-level and target-device, as set in a file 'log.conf'.
113
+ # I do not like the look of this, but it works just the way I want it to.
114
+ # "HEAVANS! Isn't there a standard way to do this in Ruby, for Christ's sake?", you say.
115
+ # Heck, I don't care. <= Read that again, I say.
116
+ def log_conf(cn = nil)
117
+ config = level = target = nil
118
+ # puts 'log-config is in ' << @@LOG_CONF
119
+ if(File::exist?(@@LOG_CONF) )
120
+ begin
121
+ conf = File.read(@@LOG_CONF)
122
+ config = instance_eval(conf)
123
+ rescue Exception => ex
124
+ STDERR.puts "WARNING! Cannot evaluate the logger-configuration!" << ' ' << ex.message
125
+ STDERR.puts "Default log-levels apply."
126
+ end
127
+ else
128
+ puts "Default log-levels apply."
129
+ end
130
+
131
+ if(config && config.respond_to?(:to_hash) )
132
+ config.default = nil
133
+ if cn
134
+ config = config[cn.to_sym]
135
+ else
136
+ config = config[self.class.name.to_sym]
137
+ end
138
+
139
+ if(config )
140
+ if(config.respond_to?(:to_ary) && config.size == 2)
141
+ @level, @target = config
142
+ @target.downcase!
143
+ logdir = File.dirname(@target)
144
+ msg = file_check(logdir, :exist?, :directory?, :writable?)
145
+ if(msg)
146
+ STDERR.puts "WARNING! A logfile for '%s' cannot be written to %s (%s)!" %[self.class.name, logdir, msg]
147
+ @target = nil
148
+ end
149
+ else
150
+ @level = config
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ ######### test
158
+ if __FILE__ == $0
159
+ class TClass
160
+ # class level ---->
161
+ self.extend(Logging)
162
+ @@log = init_logger(STDOUT, Logger::INFO)
163
+ # <------
164
+ # object-level ---->
165
+ include Logging
166
+ # <---------
167
+
168
+ def test_log
169
+ @@log.info('class-level logger called from instance: ' << @@log.to_s)
170
+ #@log = @@log # works too
171
+ @log = TClass.class_eval{@log}
172
+ @log.info('AGAIN: class-level logger called from instance: ' << @log.to_s)
173
+ @log.debug("you won't see this on log-level INFO")
174
+
175
+ # object-level ---->
176
+ init_logger
177
+ # <-----------
178
+ @log.info("That's a different thing: " << @log.to_s << " - object-level logger!")
179
+
180
+ end
181
+ def self::test_log
182
+ @log.info('class-level logger called from class: ' << @log.to_s)
183
+ @@log.info('AGAIN: class-level logger called from class: ' << @log.to_s)
184
+ end
185
+ end
186
+
187
+ TClass.new.test_log # class-logger + 1st object-logger
188
+ TClass.new.test_log # same class-logger + 2nd object-logger
189
+
190
+ TClass::test_log # same class-logger
191
+ puts 'And just say it once clearly: THIS IS COOOL!!'
192
+ end
193
+ #EOF
data/lib/sqlite2dbf.rb ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * ©2016 Michael Uplawski <michael.uplawski@uplawski.eu> *
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+
24
+
25
+ require_relative 'file_checking'
26
+ require_relative 'logging'
27
+ require 'shp'
28
+ require 'sqlite3'
29
+ require_relative 'argparser'
30
+
31
+ =begin
32
+ The main program class. Does it.
33
+ =end
34
+
35
+ class SQLite2DBF
36
+ include Logging
37
+ include Translating
38
+
39
+ def initialize(*args)
40
+ options = ArgParser::parse(args)
41
+ init_logger
42
+ level = (options.debug ? Logger::DEBUG : @log.level)
43
+ @log.level = level
44
+ @log.debug('options are: ' << options.to_s)
45
+
46
+ if(options.source)
47
+ sqlite_file = options.source
48
+ dbf_file = options.target if options.target
49
+ dbf_file = :table if options.table_name
50
+ dbf_file ||= File.dirname(sqlite_file) << File::Separator << File.basename(sqlite_file, '.*')
51
+ msg = nil
52
+
53
+ if(dbf_file != :table)
54
+ if(File.exist?(dbf_file))
55
+ msg = File_Checking.file_check(dbf_file, :file, :writable)
56
+ elsif(File.exist?(File.dirname(dbf_file)))
57
+ msg = File_Checking.file_check(File.dirname(dbf_file), :directory, :writable)
58
+ end
59
+ end
60
+
61
+ msg ||= File_Checking.file_check(sqlite_file, :exist, :readable, :file)
62
+
63
+ if(!msg)
64
+ @log.debug('will transform ' << sqlite_file << ' to ' << dbf_file.to_s << '.dbf')
65
+ transform(sqlite_file, dbf_file)
66
+ else
67
+ msg = trl("ERROR! Unsuitable file") << " : %s" %msg
68
+ @log.error(msg)
69
+ exit false
70
+ end
71
+ else
72
+ puts trl("ERROR! Source-file is a mandatory program parameter!")
73
+ puts trl("Start this program with parameter -h or --help to see the usage-message.")
74
+ end
75
+
76
+ end
77
+
78
+ private
79
+
80
+ def transform(sqlite_file, dbf_file)
81
+ # <------------ mapping SQLite-types to SHP/XBase ------------>
82
+ tmap = {'INT' => 1, 'TINYINT' => 1, 'SMALLINT' => 1, 'MEDIUMINT' => 1, 'BIGINT' => 1, 'UNSIGNED BIGINT' => 1, 'VARCHAR' => 0, 'CHARACTER' => 0, 'VARYING CHARACTER(255)' => 0, 'LONGVARCHAR' => 0, 'TEXT' => 0, 'INTEGER' => 1, 'FLOAT' => 2, 'REAL' => 2, 'DOUBLE' => 2}
83
+ # -----------> in a way ... <--------------
84
+
85
+ begin
86
+ SQLite3::Database.new(sqlite_file) do |db|
87
+ table_names = db.execute('select name from sqlite_master WHERE type="table"')
88
+ @log.debug('sqlite contains ' << table_names.size.to_s << ' table(s): ' << table_names.join(', '))
89
+ table_names.each_with_index do |tn, num|
90
+ tname = tn.join
91
+ table_info = db.table_info(tname)
92
+ @log.debug(tn[0] << ': ' << table_info.join)
93
+ content = db.execute('select * from ' << tname )
94
+ if(:table == dbf_file)
95
+ dbf_name = tname << (content.empty? ? '_empty' : '')<< '.dbf'
96
+ else
97
+ dbf_name = dbf_file.dup << num.to_s << (content.empty? ? '_empty' : '')<< '.dbf'
98
+ end
99
+ @log.debug('dbf will be ' << dbf_name)
100
+ dbt = SHP::DBF.create(dbf_name)
101
+ table_info.each_with_index do |field, index|
102
+ ftype = 0
103
+ # -----> determine the simple dbf data-type that has to do. <----
104
+ sql_type = tmap.keys.detect {|kt| field['type'].start_with?(kt) }
105
+ ftype ||= tmap[sql_type]
106
+ # <---- Yes. I know. ---->
107
+
108
+ dbt.add_field(field['name'], ftype, 200, 0)
109
+ end
110
+
111
+ content.each_with_index do |row, record_no|
112
+ @log.debug('row is ' << row.to_s)
113
+ row.each_with_index do |svalue, field_index|
114
+ type = table_info[field_index]['type']
115
+ @log.debug('field is ' << table_info[field_index]['name'] << ', svalue is ' << svalue.to_s << ', type is ' << type)
116
+ if(svalue)
117
+ dbt.write_string_attribute(record_no, field_index, svalue ) if 'TEXT' == type
118
+ begin
119
+ dbt.write_integer_attribute(record_no, field_index, svalue) if 'INTEGER' == type
120
+ dbt.write_double_attribute(record_no, field_index, svalue) if 'FLOAT' == type
121
+ rescue RangeError => ex
122
+ @log.error(trl("ERROR! cannot write value of type %s" %type) << ': ' << ex.message )
123
+ end
124
+ else
125
+ dbt.write_null_attribute(record_no, field_index) if (!svalue || type.empty?)
126
+ end
127
+ end
128
+ end
129
+ dbt.close
130
+ end
131
+ end
132
+ end
133
+ rescue SQLite3::Exception => er
134
+ @log.error trl("ERROR! Cannot read the source-file") << ' (' << sqlite_file << "): %s" %er.message << '.'
135
+ end
136
+ end
@@ -0,0 +1,91 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * ©2011-2015, Michael Uplawski *
5
+ * <michael.uplawski@uplawski.eu> *
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+
24
+
25
+ RD = File.expand_path(File.dirname(__FILE__) ) + File::SEPARATOR if !defined?(RD)
26
+
27
+ require 'yaml'
28
+ require_relative 'file_checking'
29
+
30
+
31
+ =begin
32
+ A way to produce translated text in a ruby-program.
33
+ Translations are read from a file "translations" in the program folder.
34
+ =end
35
+ module Translating
36
+ # There are better ways to extend a translated
37
+ # string, but I keep the 'wild-card' for
38
+ # historical reasons.
39
+ @@awild = 'XX'
40
+
41
+ @@lang = nil
42
+ @@lang_file = format("%s%s", RD, 'LANG')
43
+ @@tr = YAML::load_file("#{RD}translations")
44
+
45
+ # find the current language-setting and return it.
46
+ def self.language()
47
+ if @@lang == nil
48
+ r = ENV['LANG']
49
+ if(r)
50
+ @@lang = r[0, 2]
51
+ elsif( !File_Checking::file_check(@@lang_file, [:exist?, :readable?]) && File::size(@@lang_file) >= 2)
52
+ File::open(@@lang_file, 'r') {|f| @@lang = f.readline}
53
+ @@lang.chomp!.downcase! if @@lang
54
+ end
55
+ end
56
+ @@lang = 'en' if !@@lang
57
+ end
58
+
59
+ # Translate a string to the currently set langage.
60
+ # The args parameter may contain replacement-text which
61
+ # will appear at the positions indicated by wildcard-characters
62
+ # in the original string.
63
+ def self.trl(t, *args)
64
+ Translating::language()
65
+ lt = @@tr[t]
66
+ if(lt)
67
+ lt = lt[@@lang]
68
+ else
69
+ # File.open('/tmp/mtf', 'a+') {|f| f << t << "\n"}
70
+ puts "\nTRANSLATION MISSING: \"" << t << "\""
71
+ end
72
+ lt ||= t
73
+ if(args && !args.empty?)
74
+ i = -1
75
+ lt = lt.gsub(@@awild) do |a|
76
+ i += 1
77
+ args.flatten[i]
78
+ end
79
+ lt += args[i + 1, args.length].join
80
+ end
81
+ return lt
82
+ end
83
+
84
+ # Translate a string to the currently set langage.
85
+ # The args parameter may contain replacement-text which
86
+ # will appear at the positions indicated by wildcard-characters
87
+ # in the original string.
88
+ def trl(t, *args )
89
+ Translating::trl(t, args)
90
+ end
91
+ end
data/lib/translations ADDED
@@ -0,0 +1,153 @@
1
+ #
2
+ # ©2016-2016, Michael Uplawski <michael.uplawski@souris-libre.fr>
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program; if not, write to the
15
+ # Free Software Foundation, Inc.,
16
+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ # =========================================================================
18
+ # These are the messages printed by SQLite2DBF. The first line of each
19
+ # block is the original english message, the following lines contain the
20
+ # translations for different locales.
21
+
22
+ # Keep this key 'SQLite2DB' as it is
23
+
24
+ SQLite2DBF:
25
+
26
+ Usage:
27
+ de: Aufrufsyntax
28
+ fr: Syntax
29
+
30
+ -s [sqlite-file] [options]:
31
+ de: -q [SQLite-Datei] [Optionen]
32
+ fr: -s [Fichier SQLite] [Options]
33
+
34
+ or %s [Common options]:
35
+ de: oder %s [Allgemeine Optionen]
36
+ fr: ou %s [Options généraux]
37
+
38
+ Specific options:
39
+ de: Spezielle Optionen
40
+ fr: Options spécifiques
41
+
42
+ # program argument -s (source)
43
+ s:
44
+ de: q
45
+ fr: s
46
+
47
+ source/sqlite-file [FILE.sqlite]:
48
+ de: quelle (SQLite) [Datei.sqlite]
49
+ fr: source (SQLite) [Fichier.sqlite]
50
+
51
+ SQLite-file to read.:
52
+ de: SQLite Datei, die gelesen wird.
53
+ fr: Fichier SQLite qui sera lu.
54
+
55
+ # program option -o (original table-name)
56
+ o:
57
+ de: t
58
+ fr: t
59
+
60
+ --orig:
61
+ de: --tab
62
+ fr: --tab
63
+
64
+ Table-names:
65
+ de: Namen der Tabellen
66
+ fr: Noms des tableaux
67
+
68
+ Use the table-name as file-name for the DBF-result:
69
+ de: Tabellen-Namen als Dateinamen für die DBF-Ausgabe verwenden
70
+ fr: Utiliser les noms des tableaux comme noms des fichiers DBF
71
+
72
+ ERROR! cannot write value of type INTEGER:
73
+ de: FEHLER! Kann INTEGER-Wert nicht schreiben
74
+ fr: ERREUR ! Ne peux pas écrire valeur de type 'INTEGER'
75
+
76
+ # program argument -t (target)
77
+ t:
78
+ de: z
79
+ fr: c
80
+
81
+ dBase-files [FILE(0...n).dbf]:
82
+ de: dBase Dateien [Datei(0...n).dbf]
83
+ fr: cible Fichier dBase [Fichier(0...n).dbf]
84
+
85
+ Name for the dBase-files (1 per table) to be written.:
86
+ de: Name der dBase-Dateien (1 pro Tabelle), die geschrieben werden.
87
+ fr: Nom des fichiers (1 par tableau) qui seront écris.
88
+
89
+ Common options:
90
+ de: Allgemeine Optionen
91
+ fr: Options généraux
92
+
93
+ # program argument -d (debug)
94
+ -d:
95
+ de: -d
96
+ fr: -d
97
+
98
+ --debug:
99
+ de: --debug
100
+ fr: --debug
101
+
102
+ Show debug-messages:
103
+ de: Debug Meldungen zeigen
104
+ fr: Afficher tous les messages
105
+
106
+ # program option -h (help)
107
+ -h:
108
+ de: -h
109
+ fr: -a
110
+
111
+ --help:
112
+ de: --hilfe
113
+ fr: --aide
114
+
115
+ Show this message:
116
+ de: Diese Nachricht anzeigen
117
+ fr: Afficher ce message
118
+
119
+ # program option -v (version)
120
+ -v:
121
+ de: -v
122
+ fr: -v
123
+
124
+ --version:
125
+ de: --version
126
+ fr: --version
127
+
128
+ Show version and program information:
129
+ de: Versions- und Programminformationen anzeigen
130
+ fr: Afficher des informations sur le logiciel et sa version
131
+
132
+ ERROR! Source-file is a mandatory program parameter!:
133
+ de: FEHLER! Quelldatei ist ein obligatorischer Programmparameter!
134
+ fr: ERREUR ! Source est un paramètre obligatoire !
135
+
136
+ Start this program with parameter -h or --help to see the usage-message.:
137
+ de: Wenn Sie das Programm mit dem Parameter -h oder mit --hilfe starten, wird die Eingabsyntax angezeigt.
138
+ fr: Lancez le logiciel avec le paramètre -a ou avec --aide, pour voir la syntax de l'entrée.
139
+
140
+ ERROR! Unsuitable or incomplete program-arguments:
141
+ de: FEHLER! Ungeeignete oder unvollständige Programmparameter
142
+ fr: ERREUR ! Paramètres invalides ou incomplètes
143
+
144
+ ERROR! Unsuitable file:
145
+ de: FEHLER! Ungeeignete Datei!
146
+ fr: ERREUR ! Fichier inapte !
147
+
148
+ ERROR! Cannot read the source-file:
149
+ de: FEHLER! Kann die Quelldatei nicht lesen
150
+ fr: ERREUR ! Source inlisible
151
+
152
+
153
+ # eof
@@ -0,0 +1,15 @@
1
+ require_relative 'lib/constants'
2
+ Gem::Specification.new do |s|
3
+ s.name = $APPNAME
4
+ s.version = $VERSION
5
+ s.date = $DATE
6
+ s.summary = "missing files added."
7
+ s.description = "converts SQLite to DBase"
8
+ s.authors = $AUTHORS
9
+ s.email = $EMAIL
10
+ s.files = %w~sqlite2dbf~.collect{|f| 'bin/' << f} + %w~constants.rb argparser.rb sqlite2dbf.rb file_checking.rb log.conf logging.rb translating.rb translations ~.collect{|f| 'lib/' << f} + %w~sqlite2dbf.gemspec~.collect{|f|f}
11
+ s.requirements = 'shp, sqlite3'
12
+ s.executables = 'sqlite2dbf'
13
+ s.license = $LICENSE
14
+ s.required_ruby_version = '>= 2.3'
15
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqlite2dbf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
5
+ platform: ruby
6
+ authors:
7
+ - Michael Uplawski <michael.uplawski@uplawski.eu>
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: converts SQLite to DBase
14
+ email: michael.uplawski@uplawski.eu
15
+ executables:
16
+ - sqlite2dbf
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/sqlite2dbf
21
+ - lib/argparser.rb
22
+ - lib/constants.rb
23
+ - lib/file_checking.rb
24
+ - lib/log.conf
25
+ - lib/logging.rb
26
+ - lib/sqlite2dbf.rb
27
+ - lib/translating.rb
28
+ - lib/translations
29
+ - sqlite2dbf.gemspec
30
+ homepage:
31
+ licenses:
32
+ - GPL-3.0
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '2.3'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements:
49
+ - shp, sqlite3
50
+ rubyforge_project:
51
+ rubygems_version: 2.6.7
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: missing files added.
55
+ test_files: []