sqlite2dbf 0.1.8 → 0.2
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 +4 -4
- data/lib/argparser.rb +83 -73
- data/lib/config +104 -0
- data/lib/configuration.rb +114 -0
- data/lib/constants.rb +2 -2
- data/lib/file_checking.rb +48 -48
- data/lib/log.conf +3 -0
- data/lib/logging.rb +131 -131
- data/lib/mapping.rb +94 -0
- data/lib/sqlite2dbf.rb +156 -129
- data/lib/translating.rb +56 -52
- data/lib/translations +132 -43
- data/sqlite2dbf.gemspec +2 -2
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ff3c85738ba063a8b74ca3729e4f4d34fd0310f
|
4
|
+
data.tar.gz: abfe59914da80f1118822e0a3ebf91a93c5f5a40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef5cbc10c43925b74b319b9049d81ccd9c04e95d2158ddb0954f7232377eff0c2a3323cd4b333193e3947bd7599bdbe0081baa6f8d59752fc77c432bb682048e
|
7
|
+
data.tar.gz: 48b7629bcf6b490f3f1396d61991a48134a1b6dc05be084136bd49cd0bafbbac7b77714e84a344adb3a50f7d0c1fc1d7211231ba12d1879ba40ce02494807544
|
data/lib/argparser.rb
CHANGED
@@ -30,46 +30,56 @@ require_relative 'constants'
|
|
30
30
|
|
31
31
|
class ArgParser
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
33
|
+
self.extend(Logging)
|
34
|
+
self.extend(Translating)
|
35
|
+
@@log = init_logger()
|
36
|
+
|
37
|
+
# Returns a structure describing the options.
|
38
|
+
#
|
39
|
+
def self.parse(args)
|
40
|
+
# The options specified on the command line will be collected in <b>options</b>.
|
41
|
+
# We set default values here.
|
42
|
+
|
43
|
+
options = OpenStruct.new
|
44
|
+
|
45
|
+
op = OptionParser.new do |opts|
|
46
|
+
opts.banner = "\n" << trl("Usage") << ":\t" << $APPNAME.dup << ' ' << trl("-s [SQLite-file] [options]") << "\n\t" << trl("or %s [Common options]") %($APPNAME)
|
47
|
+
|
48
|
+
opts.separator ""
|
49
|
+
opts.separator trl("Specific options") << ':'
|
50
|
+
|
51
|
+
opts.on('-' << trl("s"), '--' << trl("source [PATH]"), trl( "SQLite-file to read.")) do |source|
|
52
|
+
options.source = source
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on('-' << trl('c'), '--' << trl("config [PATH]"), trl('Configuration file for this transformation')) do |config|
|
56
|
+
options.config = config
|
57
|
+
end
|
58
|
+
|
59
|
+
opts.on('-' << trl('n'), '--' << trl("name [TABLE]"), trl('The name of the table from the SQLite-database to convert')) do |name|
|
60
|
+
options.name = name
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.on('-' << trl("t"), '--' << trl("target [PATH]"), trl( "Path to the dBase-file to be written.")) do |target|
|
64
|
+
options.target = target
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on('-' << trl("l"), '--' << trl("list"), trl( "Show the list of available tables and exit")) do |target|
|
68
|
+
options.list = true
|
69
|
+
end
|
70
|
+
|
71
|
+
opts.on('-' << trl('o'), '--' << trl("out [PATH]"), trl('Use the table-name as file-name for the DBF-result, store output in PATH')) do |path|
|
72
|
+
options.name_like_table = true
|
73
|
+
options.out = path
|
74
|
+
end
|
75
|
+
|
76
|
+
opts.on('--' << trl("time [list]"), trl( "Fields (table-columns) which shall be handled as timestamp values.")) do |list|
|
77
|
+
options.time = list.gsub(/[,;]/, '').split
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.on('--' << trl("date [list]"), trl( "Fields (table-columns) which shall be handled as date-time values.")) do |list|
|
81
|
+
options.datetime = list.gsub(/[,;]/, '').split
|
82
|
+
end
|
73
83
|
|
74
84
|
=begin
|
75
85
|
|
@@ -87,39 +97,39 @@ opts.on("-g", "--generic [CONFIG FILE]",
|
|
87
97
|
options.generic = File.expand_path(file )
|
88
98
|
end
|
89
99
|
=end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
100
|
+
opts.separator ""
|
101
|
+
opts.separator trl("Common options") << ':'
|
102
|
+
|
103
|
+
# No argument, shows at tail. This will print an options summary.
|
104
|
+
#
|
105
|
+
opts.on_tail(trl("-d"), trl("--debug"), trl("Show debug-messages") ) do
|
106
|
+
options.debug = true
|
107
|
+
@@log.level = Logger::DEBUG
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
opts.on_tail(trl("-h"), trl("--help"), trl("Show this message") ) do
|
112
|
+
puts opts
|
113
|
+
exit true
|
114
|
+
end
|
115
|
+
|
116
|
+
opts.on_tail(trl("-v"), trl("--version"), trl("Show version and program information") ) do
|
117
|
+
puts "\t#{$APPNAME}"
|
118
|
+
puts "\t© #{$YEARS}, <#{$AUTHORS.join(', ')}>"
|
119
|
+
exit true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
begin
|
123
|
+
op.parse!(args)
|
124
|
+
rescue OptionParser::ParseError => er
|
125
|
+
msg = trl("ERROR! Unsuitable or incomplete program-arguments") << (": %s" %er.message )
|
126
|
+
puts msg
|
127
|
+
puts trl("Start this program with parameter -h or --help to see the usage-message.")
|
128
|
+
exit false
|
129
|
+
end
|
130
|
+
|
131
|
+
options
|
132
|
+
end # parse()
|
123
133
|
|
124
134
|
end
|
125
135
|
|
data/lib/config
ADDED
@@ -0,0 +1,104 @@
|
|
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
|
+
|
19
|
+
# Exemplary configuration file for sqlite2dbf.
|
20
|
+
# Overwrite the settings in this file by either naming a different file with
|
21
|
+
# the --config parameter or by specifying each or some of the options on the
|
22
|
+
# command-line.
|
23
|
+
|
24
|
+
# The syntax of this file or your own versions is simple:
|
25
|
+
# Under the name of an option, you note the value that the option should adopt.
|
26
|
+
# Indent the value by 1 space minimum. The option-names are identical to the
|
27
|
+
# long options, which can be used on the command-line, like, for example
|
28
|
+
# --source.
|
29
|
+
#
|
30
|
+
# Example: If you transform the always same database with this
|
31
|
+
# configuration-file, you note the path to the SQLite-file under the option
|
32
|
+
# “source:”, like this:
|
33
|
+
# source:
|
34
|
+
# /path/to_the/database/file.sqlite
|
35
|
+
# i.e. with one or several spaces in front of the value. Lines with a leading
|
36
|
+
# hashmark are comments. Keep them intact.
|
37
|
+
#
|
38
|
+
# The following option “save_what” is not used by SQlite2DBF but shall serve as
|
39
|
+
# EXAMPLE.
|
40
|
+
save_what:
|
41
|
+
our_ship
|
42
|
+
|
43
|
+
# -------------- Define your own settings below this line -------------------
|
44
|
+
#
|
45
|
+
# The source-file (sqlite).
|
46
|
+
#
|
47
|
+
# Value: a SQLite database file which can be opened for reading.
|
48
|
+
# Example: /data/my_database/customers.sqlite
|
49
|
+
# ./my_employers.sqlite
|
50
|
+
# F:\\Path_to_database\Products.db
|
51
|
+
# Default: empty (required on the command-line)
|
52
|
+
source:
|
53
|
+
|
54
|
+
# The name of the table, which is converted.
|
55
|
+
#
|
56
|
+
# Value: A string which corresponds to the name of a
|
57
|
+
# table in the SQLite-database
|
58
|
+
# Example: employees
|
59
|
+
# Price-list
|
60
|
+
# Default: empty (required on the command-line)
|
61
|
+
name:
|
62
|
+
|
63
|
+
# The target-file (dBase).
|
64
|
+
#
|
65
|
+
# Value: The path to the file, that should be written.
|
66
|
+
# Example: /data/my_database/customers.dbf
|
67
|
+
# ./my_employers.dbf
|
68
|
+
# F:\\Path_to_database\Products.dbf
|
69
|
+
# Default: empty (NOT required)
|
70
|
+
target:
|
71
|
+
|
72
|
+
# Fields which shall be treated as time.
|
73
|
+
#
|
74
|
+
# Value: One field-name or a list of space-separated
|
75
|
+
# field-names (columns).
|
76
|
+
# Example: created
|
77
|
+
# "created last_accessed"
|
78
|
+
# Default: empty (NOT required)
|
79
|
+
time:
|
80
|
+
|
81
|
+
# Fields which shall be treated as date-time.
|
82
|
+
#
|
83
|
+
# Value: One field-name or a list of space-separated field-names (columns).
|
84
|
+
# Example: joined
|
85
|
+
# "expires since last_update"
|
86
|
+
# Default: empty (NOT required)
|
87
|
+
date: last_visit_date
|
88
|
+
|
89
|
+
# Shall the dBase-file be named after the table? Is set by specifying a
|
90
|
+
# target-directory as value to this option.
|
91
|
+
#
|
92
|
+
# Value: Path to the target directory
|
93
|
+
# Example: /data/base/dBase/
|
94
|
+
# Default: empty (NOT required)
|
95
|
+
out:
|
96
|
+
|
97
|
+
# Shall debug messages be printed out? You can modify the logging-
|
98
|
+
# options also in the file log.conf, that you find in the sub-directory lib of
|
99
|
+
# the gem-directory. This way, you can direct all output to 1 or several files.
|
100
|
+
#
|
101
|
+
# Value: true, yes, false or no (same as empty)
|
102
|
+
# Example: yes
|
103
|
+
# Default: empty/no/false (NOT required)
|
104
|
+
debug:
|
@@ -0,0 +1,114 @@
|
|
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
|
+
require 'yaml'
|
23
|
+
require 'singleton'
|
24
|
+
require 'ostruct'
|
25
|
+
require_relative 'file_checking'
|
26
|
+
require_relative 'logging'
|
27
|
+
require_relative 'translating'
|
28
|
+
|
29
|
+
class Configuration
|
30
|
+
include File_Checking
|
31
|
+
include Logging
|
32
|
+
include Singleton
|
33
|
+
include Translating
|
34
|
+
|
35
|
+
# default configuration file
|
36
|
+
@@config_file = File::dirname(__FILE__) << File::Separator << 'config'
|
37
|
+
|
38
|
+
# do initializations
|
39
|
+
def initialize()
|
40
|
+
init_logger()
|
41
|
+
end
|
42
|
+
|
43
|
+
# Configure with the command-line arguments.
|
44
|
+
def set(options)
|
45
|
+
@log.debug('options are: ' << options.to_s )
|
46
|
+
# User-provided configuration-file?
|
47
|
+
if(options['config'])
|
48
|
+
cf = options['config']
|
49
|
+
msg = check_file(cf, :file, :readable)
|
50
|
+
if(!msg)
|
51
|
+
@@config_file = cf
|
52
|
+
else
|
53
|
+
msg = trl("The file %s " << msg.split[1,100].join(' ')) %msg.split[0]
|
54
|
+
@log.error(trl("ERROR! Unsuitable file") << ' ' << msg)
|
55
|
+
give_up
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@log.debug('config-file is ' << @@config_file)
|
60
|
+
# read defaults from configuration-file
|
61
|
+
co = OpenStruct.new(YAML::load_file(@@config_file))
|
62
|
+
# merge and overwrite with the comman-line arguments
|
63
|
+
@config = co.to_h.merge(options.to_h)
|
64
|
+
@log.debug('config is now: ' << @config.to_s )
|
65
|
+
verify
|
66
|
+
end
|
67
|
+
|
68
|
+
# return any value stored in @config
|
69
|
+
def method_missing(msg, *args)
|
70
|
+
ms = msg.to_sym
|
71
|
+
# Exception-handling is not a control-structure.
|
72
|
+
# This is.
|
73
|
+
if @config[ms]
|
74
|
+
return @config[ms]
|
75
|
+
else
|
76
|
+
return nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# exit on error
|
83
|
+
def give_up
|
84
|
+
@log.error("\t" << trl("Aborting. Bye!"))
|
85
|
+
exit false
|
86
|
+
end
|
87
|
+
|
88
|
+
# Do a maximum of verifications.
|
89
|
+
# Not everything is possible before the database has been read.
|
90
|
+
def verify
|
91
|
+
msg = nil
|
92
|
+
# ensure :source is set
|
93
|
+
if(! @config[:source] )
|
94
|
+
msg = trl('missing argument %s') %'source'
|
95
|
+
# either :name or :list are needed in addition
|
96
|
+
elsif (!@config[:name] && !@config[:list])
|
97
|
+
msg = trl("Either --name (-n) or --list (-l) is needed as additional program-argument" )
|
98
|
+
end
|
99
|
+
|
100
|
+
# avoid contradicting options
|
101
|
+
if !msg && @config[:target] && @config[:out]
|
102
|
+
msg = trl("contradictory arguments (%s):" %['target', 'out'])
|
103
|
+
end
|
104
|
+
|
105
|
+
if msg
|
106
|
+
@log.error msg
|
107
|
+
@log.error(trl("Start this program with parameter -h or --help to see the usage-message.") )
|
108
|
+
give_up
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
#eof
|
data/lib/constants.rb
CHANGED
data/lib/file_checking.rb
CHANGED
@@ -27,57 +27,57 @@ but maybe you find it useful.
|
|
27
27
|
=end
|
28
28
|
module File_Checking
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
msg
|
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]}"
|
79
75
|
end
|
80
|
-
|
76
|
+
end
|
77
|
+
end
|
78
|
+
msg
|
79
|
+
end
|
80
|
+
alias :check_file :file_check
|
81
81
|
end
|
82
82
|
|
83
83
|
=begin
|