sqlite2dbf 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []