sqlite2dbf 0.1.8 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|