caruby-core 1.4.7 → 1.4.9
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.
- data/History.txt +11 -0
- data/README.md +1 -1
- data/lib/caruby/cli/command.rb +27 -3
- data/lib/caruby/csv/csv_mapper.rb +2 -0
- data/lib/caruby/csv/csvio.rb +187 -169
- data/lib/caruby/database.rb +33 -16
- data/lib/caruby/database/lazy_loader.rb +23 -23
- data/lib/caruby/database/persistable.rb +32 -18
- data/lib/caruby/database/persistence_service.rb +20 -7
- data/lib/caruby/database/reader.rb +22 -21
- data/lib/caruby/database/search_template_builder.rb +7 -9
- data/lib/caruby/database/sql_executor.rb +52 -27
- data/lib/caruby/database/store_template_builder.rb +18 -13
- data/lib/caruby/database/writer.rb +107 -44
- data/lib/caruby/domain/attribute_metadata.rb +35 -25
- data/lib/caruby/domain/java_attribute_metadata.rb +43 -20
- data/lib/caruby/domain/merge.rb +9 -5
- data/lib/caruby/domain/reference_visitor.rb +4 -3
- data/lib/caruby/domain/resource_attributes.rb +52 -12
- data/lib/caruby/domain/resource_dependency.rb +129 -42
- data/lib/caruby/domain/resource_introspection.rb +1 -1
- data/lib/caruby/domain/resource_inverse.rb +20 -3
- data/lib/caruby/domain/resource_metadata.rb +20 -4
- data/lib/caruby/domain/resource_module.rb +190 -124
- data/lib/caruby/import/java.rb +39 -19
- data/lib/caruby/migration/migratable.rb +31 -6
- data/lib/caruby/migration/migrator.rb +126 -40
- data/lib/caruby/migration/uniquify.rb +0 -1
- data/lib/caruby/resource.rb +28 -5
- data/lib/caruby/util/attribute_path.rb +0 -2
- data/lib/caruby/util/class.rb +8 -5
- data/lib/caruby/util/collection.rb +5 -3
- data/lib/caruby/util/domain_extent.rb +0 -3
- data/lib/caruby/util/options.rb +10 -9
- data/lib/caruby/util/person.rb +41 -12
- data/lib/caruby/util/pretty_print.rb +1 -1
- data/lib/caruby/util/validation.rb +0 -28
- data/lib/caruby/version.rb +1 -1
- data/test/lib/caruby/import/java_test.rb +26 -9
- data/test/lib/caruby/migration/test_case.rb +103 -0
- data/test/lib/caruby/test_case.rb +231 -0
- data/test/lib/caruby/util/class_test.rb +2 -2
- data/test/lib/caruby/util/visitor_test.rb +3 -2
- data/test/lib/examples/galena/clinical_trials/migration/participant_test.rb +28 -0
- data/test/lib/examples/galena/clinical_trials/migration/test_case.rb +40 -0
- metadata +195 -170
- data/lib/caruby/domain/attribute_initializer.rb +0 -16
- data/test/lib/caruby/util/validation_test.rb +0 -14
data/History.txt
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
This history lists major release themes. See the GitHub source (https://github.com/caruby/core)
|
2
|
+
for change details.
|
3
|
+
|
1
4
|
=== 1.4.1 / 2010-11-23
|
2
5
|
|
3
6
|
* Initial public release.
|
@@ -30,4 +33,12 @@
|
|
30
33
|
|
31
34
|
* Support annotation migration.
|
32
35
|
|
36
|
+
=== 1.4.8 / 2011-05-03
|
37
|
+
|
38
|
+
* Fix annotation migration error.
|
39
|
+
|
40
|
+
* Refactor resource import.
|
41
|
+
|
42
|
+
=== 1.4.9 / 2011-05-04
|
33
43
|
|
44
|
+
* Support Oracle driver.
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Feature List
|
|
27
27
|
|
28
28
|
Installing
|
29
29
|
----------
|
30
|
-
caRuby is installed automatically when an application gem, e.g. caruby-tissue,
|
30
|
+
caRuby is installed automatically when an application gem, e.g. [caruby-tissue](http://caruby.rubyforge.org/catissue.html),
|
31
31
|
is installed.
|
32
32
|
|
33
33
|
Usage
|
data/lib/caruby/cli/command.rb
CHANGED
@@ -47,8 +47,11 @@ module CaRuby
|
|
47
47
|
# @yieldparam (see #run)
|
48
48
|
def initialize(specs=[], &executor)
|
49
49
|
@executor = executor
|
50
|
+
# Options start with a dash, arguments are whatever is left.
|
50
51
|
@opt_specs, @arg_specs = specs.partition { |spec| spec[1][0, 1] == '-' }
|
52
|
+
# Add the default option specifications.
|
51
53
|
@opt_specs.concat(DEF_OPTS)
|
54
|
+
# The application name is the command.
|
52
55
|
super($0)
|
53
56
|
end
|
54
57
|
|
@@ -70,6 +73,7 @@ module CaRuby
|
|
70
73
|
|
71
74
|
private
|
72
75
|
|
76
|
+
# The default options that apply to all commands.
|
73
77
|
DEF_OPTS = [
|
74
78
|
[:help, "-h", "--help", "Display this help message"],
|
75
79
|
[:file, "--file FILE", "Configuration file containing other options"],
|
@@ -78,6 +82,7 @@ module CaRuby
|
|
78
82
|
[:quiet, "-q", "--quiet", "Suppress printing messages to stdout"]
|
79
83
|
]
|
80
84
|
|
85
|
+
# @param [{Symbol => Object}] opts the option => value hash
|
81
86
|
def call_executor(opts)
|
82
87
|
if @executor.nil? then raise CommandError.new("Command #{self} does not have an execution block") end
|
83
88
|
@executor.call(opts)
|
@@ -87,14 +92,19 @@ module CaRuby
|
|
87
92
|
#
|
88
93
|
# @return [{Symbol => Object}] the option => value hash
|
89
94
|
def get_opts
|
95
|
+
# the options hash
|
90
96
|
opts = {}
|
91
97
|
# the option parser
|
92
98
|
OptionParser.new do |parser|
|
99
|
+
# The help argument string is comprised of the argument specification labels.
|
93
100
|
arg_s = @arg_specs.map { |spec| spec[1] }.join(' ')
|
101
|
+
# Build the usage message.
|
94
102
|
parser.banner = "Usage: #{parser.program_name} [options] #{arg_s}"
|
95
103
|
parser.separator ""
|
96
104
|
parser.separator "Options:"
|
105
|
+
# parse the options
|
97
106
|
opts = parse(parser)
|
107
|
+
# grab the usage message
|
98
108
|
@usage = parser.help
|
99
109
|
end
|
100
110
|
opts
|
@@ -105,22 +115,36 @@ module CaRuby
|
|
105
115
|
# @return [{Symbol => Object}] the argument => value hash
|
106
116
|
def get_args
|
107
117
|
return Hash::EMPTY_HASH if ARGV.empty?
|
118
|
+
if @arg_specs.empty? then too_many_arguments end
|
119
|
+
# Collect the arguments from the command line.
|
108
120
|
args = {}
|
121
|
+
# The number of command line arguments or all but the last argument specifications,
|
122
|
+
# whichever is less. The last argument can have more than one value, indicated by
|
123
|
+
# the argument specification form '...', so it is processed separately below.
|
109
124
|
n = [ARGV.size, @arg_specs.size - 1].min
|
125
|
+
# the single-valued arguments
|
110
126
|
n.times { |i| args[@arg_specs[i].first] = ARGV[i] }
|
127
|
+
# Process the last argument.
|
111
128
|
if n < ARGV.size then
|
112
129
|
arg, form = @arg_specs.last
|
130
|
+
# A multi-valued last argument is the residual command argument array.
|
131
|
+
# A single-valued last argument is the last value, if there is exactly one.
|
132
|
+
# Otherwise, there are too many arguments.
|
113
133
|
if form.index('...') then
|
114
134
|
args[arg] = ARGV[n..-1]
|
115
135
|
elsif @arg_specs.size == ARGV.size then
|
116
136
|
args[arg] = ARGV[n]
|
117
137
|
else
|
118
|
-
|
138
|
+
too_many_arguments
|
119
139
|
end
|
120
140
|
end
|
121
141
|
args
|
122
142
|
end
|
123
143
|
|
144
|
+
def too_many_arguments
|
145
|
+
halt("Too many arguments - expected #{@arg_specs.size}, found: #{ARGV.join(' ')}.", 1)
|
146
|
+
end
|
147
|
+
|
124
148
|
# @param [OptionParser] parser the option parser
|
125
149
|
# @return [{Symbol => Object}] the option => value hash
|
126
150
|
def parse(parser)
|
@@ -167,8 +191,8 @@ module CaRuby
|
|
167
191
|
|
168
192
|
# Prints the given message and program usage, then exits with the given status.
|
169
193
|
def halt(message=nil, status=0)
|
170
|
-
|
171
|
-
|
194
|
+
puts(message) if message
|
195
|
+
puts(@usage)
|
172
196
|
exit(status)
|
173
197
|
end
|
174
198
|
end
|
data/lib/caruby/csv/csvio.rb
CHANGED
@@ -6,180 +6,198 @@ require 'faster_csv'
|
|
6
6
|
require 'caruby/util/options'
|
7
7
|
require 'caruby/util/collection'
|
8
8
|
|
9
|
-
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# *
|
13
|
-
# *
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# CsvIO is Enumerable, but does not implement the complete Ruby IO interface.
|
20
|
-
class CsvIO
|
21
|
-
include Enumerable
|
22
|
-
|
23
|
-
# Returns the CSV field access header symbols.
|
24
|
-
attr_reader :headers
|
25
|
-
|
26
|
-
# Opens the CSV file and calls the given block with this CsvIO as the argument.
|
9
|
+
module CaRuby
|
10
|
+
# CsvIO reads or writes CSV records.
|
11
|
+
# This class wraps a FasterCSV with the following modifications:
|
12
|
+
# * relax the date parser to allow dd/mm/yyyy dates
|
13
|
+
# * don't convert integer text with a leading zero to an octal number
|
14
|
+
# * allow one custom converter with different semantics: if the converter block
|
15
|
+
# call returns nil, then continue conversion, otherwise return the converter
|
16
|
+
# result. This differs from FasterCSV converter semantics which calls converters
|
17
|
+
# as long the result == the input field value. The CsvIO converter semantics
|
18
|
+
# supports converters that intend a String result to be the converted result.
|
27
19
|
#
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
# CsvIO is Enumerable, but does not implement the complete Ruby IO interface.
|
21
|
+
class CsvIO
|
22
|
+
include Enumerable
|
23
|
+
|
24
|
+
# Returns the CSV field access header symbols.
|
25
|
+
attr_reader :headers
|
26
|
+
|
27
|
+
# Opens the CSV file and calls the given block with this CsvIO as the argument.
|
28
|
+
#
|
29
|
+
# @param (see #initialize)
|
30
|
+
# @option (see #initialize)
|
31
|
+
# @yield [csvio] the optional block to execute
|
32
|
+
# @yieldparam [CsvIO] csvio the open CSVIO instance
|
33
|
+
def self.open(file, opts=nil)
|
34
|
+
csvio = new(file, opts)
|
35
|
+
if block_given? then
|
36
|
+
yield csvio
|
37
|
+
csvio.close
|
38
|
+
end
|
34
39
|
end
|
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
|
-
|
40
|
+
|
41
|
+
# {#open}s the given CSV file and calls {#each} with the given block.
|
42
|
+
#
|
43
|
+
# @param (see #initialize)
|
44
|
+
# @option (see #initialize)
|
45
|
+
# @yield [row] the block to execute on the row
|
46
|
+
# @yieldparam [{Symbol => Object}] row the field symbol => value hash
|
47
|
+
def self.foreach(file, opts=nil, &block)
|
48
|
+
open(file, opts) { |csvio| csvio.each(&block) }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Creates a new CsvIO for the specified source file.
|
52
|
+
# If a converter block is given, then it is added to the CSV converters list.
|
53
|
+
#
|
54
|
+
# @param [String] file the input CSV file to open
|
55
|
+
# @param [Hash] opts the open options
|
56
|
+
# @option opts [String] :mode the input mode (default +r+)
|
57
|
+
# @option opts [String] :headers the input field headers
|
58
|
+
# @yield [value, info] converts the input value
|
59
|
+
# @yieldparam [String] value the input value
|
60
|
+
# @yieldparam info the current field's FasterCSV FieldInfo metadata
|
61
|
+
def initialize(file, opts=nil, &converter)
|
62
|
+
# the CSV file open mode
|
63
|
+
mode = Options.get(:mode, opts, 'r')
|
64
|
+
# the CSV headers option; can be boolean or array
|
65
|
+
hdr_opt = Options.get(:headers, opts)
|
66
|
+
# there is a header record by default for an input CSV file
|
67
|
+
hdr_opt ||= true if mode =~ /^r/
|
68
|
+
# make parent directories if necessary for an output CSV file
|
69
|
+
File.makedirs(File.dirname(file)) if mode =~ /^w/
|
70
|
+
# if headers aren't given, then convert the input CSV header record names to underscore symbols
|
71
|
+
hdr_cvtr = :symbol unless Enumerable === hdr_opt
|
72
|
+
# make a custom converter
|
73
|
+
custom = Proc.new { |value, info| convert(value, info, &converter) }
|
74
|
+
# open the CSV file
|
75
|
+
@csv = FasterCSV.open(file, mode, :headers => hdr_opt, :header_converters => hdr_cvtr, :return_headers => true, :write_headers => true, :converters => custom)
|
76
|
+
# the header => field name hash:
|
77
|
+
# if the header option is set to true, then read the input header line.
|
78
|
+
# otherwise, parse an empty string which mimics an input header line.
|
79
|
+
hdr_row = case hdr_opt
|
80
|
+
when true then
|
81
|
+
@csv.shift
|
82
|
+
when Enumerable then
|
83
|
+
''.parse_csv(:headers => hdr_opt, :header_converters => :symbol, :return_headers => true)
|
84
|
+
else
|
85
|
+
raise ArgumentError.new("CSV headers option value not supported: #{hdr_opt}")
|
86
|
+
end
|
87
|
+
# the header row headers
|
88
|
+
@headers = hdr_row.headers
|
89
|
+
# the header name => symbol map
|
90
|
+
@hdr_sym_hash = hdr_row.to_hash.invert
|
91
|
+
end
|
92
|
+
|
93
|
+
# Closes the CSV file and trash file if necessary.
|
94
|
+
def close
|
95
|
+
@csv.close
|
96
|
+
@trash.close if @trash
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns the header accessor method for the given input header name.
|
100
|
+
def accessor(header)
|
101
|
+
@hdr_sym_hash[header]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sets the trash output file. This creates a separate CSV output file distinct from the input CSV file.
|
105
|
+
# This is useful for writing rejected rows from the input. The output file has a header row.
|
106
|
+
def trash=(file)
|
107
|
+
@trash = FasterCSV.open(file, 'w', :headers => true, :header_converters => :symbol, :write_headers => true)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Writes the row to the trash file if the trash file is set.
|
111
|
+
#
|
112
|
+
#@param [{Symbol => Object}] row the rejected input row
|
113
|
+
def reject(row)
|
114
|
+
@trash << row if @trash
|
115
|
+
end
|
116
|
+
|
117
|
+
# Iterates over each CSV row, yielding a row for each iteration.
|
118
|
+
# This method closes the CSV file after the iteration completes.
|
119
|
+
def each
|
120
|
+
begin
|
121
|
+
# parse each line
|
122
|
+
@csv.each { |row| yield row }
|
123
|
+
ensure
|
124
|
+
close
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return the next CSV row
|
129
|
+
# @see #each
|
130
|
+
def read
|
64
131
|
@csv.shift
|
65
|
-
when Enumerable then
|
66
|
-
''.parse_csv(:headers => hdr_opt, :header_converters => :symbol, :return_headers => true)
|
67
|
-
else
|
68
|
-
raise ArgumentError.new("CSV headers option value not supported: #{hdr_opt}")
|
69
132
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@csv.close
|
79
|
-
@trash.close if @trash
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns the header accessor method for the given input header name.
|
83
|
-
def accessor(header)
|
84
|
-
@hdr_sym_hash[header]
|
85
|
-
end
|
86
|
-
|
87
|
-
# Sets the trash output file. This creates a separate CSV output file distinct from the input CSV file.
|
88
|
-
# This is useful for writing rejected rows from the input. The output file has a header row.
|
89
|
-
def trash=(file)
|
90
|
-
@trash = FasterCSV.open(file, 'w', :headers => true, :header_converters => :symbol, :write_headers => true)
|
91
|
-
end
|
92
|
-
|
93
|
-
# Writes the row to the trash file if the trash file is set.
|
94
|
-
#
|
95
|
-
#@param [{Symbol => Object}] row the rejected input row
|
96
|
-
def reject(row)
|
97
|
-
@trash << row if @trash
|
98
|
-
end
|
99
|
-
|
100
|
-
# Iterates over each CSV row, yielding a row for each iteration.
|
101
|
-
# This method closes the CSV file after the iteration completes.
|
102
|
-
def each
|
103
|
-
begin
|
104
|
-
# parse each line
|
105
|
-
@csv.each { |row| yield row }
|
106
|
-
ensure
|
107
|
-
close
|
133
|
+
|
134
|
+
alias :shift :read
|
135
|
+
|
136
|
+
# Writes the given row to the CSV file.
|
137
|
+
#
|
138
|
+
#@param [{Symbol => Object}] row the input row
|
139
|
+
def write(row)
|
140
|
+
@csv << row
|
108
141
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
alias :shift :read
|
118
|
-
|
119
|
-
# Writes the given row to the CSV file.
|
120
|
-
#
|
121
|
-
#@param [{Symbol => Object}] row the input row
|
122
|
-
def write(row)
|
123
|
-
@csv << row
|
124
|
-
end
|
125
|
-
|
126
|
-
alias :<< :write
|
127
|
-
|
128
|
-
private
|
129
|
-
|
130
|
-
# 3-letter months => month sequence hash.
|
131
|
-
MMM_MM_MAP = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'].to_compact_hash_with_index do |mmm, index|
|
132
|
-
index < 9 ? ('0' + index.succ.to_s) : index.succ.to_s
|
133
|
-
end
|
134
|
-
|
135
|
-
# DateMatcher relaxes the FasterCSV DateMatcher to allow dd/mm/yyyy dates.
|
136
|
-
DateMatcher = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} | \d{1,2}-\w{3}-\d{2,4} | \d{4}[-\/]\d{1,2}[-\/]\d{1,2} | \d{1,2}[-\/]\d{1,2}[-\/]\d{2,4} )\z /x
|
137
|
-
|
138
|
-
# @param f the input field value to convert
|
139
|
-
# @param info the CSV field info
|
140
|
-
# @return the converted value
|
141
|
-
def convert(f, info)
|
142
|
-
return if f.nil?
|
143
|
-
# the block has precedence
|
144
|
-
value = yield(f, info) if block_given?
|
145
|
-
# integer conversion
|
146
|
-
value ||= Integer(f) if f =~ /^[1-9]\d*$/
|
147
|
-
# date conversion
|
148
|
-
value ||= convert_date(f) if f =~ CsvIO::DateMatcher
|
149
|
-
# float conversion
|
150
|
-
value ||= (Float(f) rescue f) if f =~ /^\d+\.\d*$/ or f =~ /^\d*\.\d+$/
|
151
|
-
# return converted value or the input field if there was no conversion
|
152
|
-
value || f
|
153
|
-
end
|
154
|
-
|
155
|
-
# @param [String] the input field value
|
156
|
-
# @return [Date] the converted date
|
157
|
-
def convert_date(f)
|
158
|
-
# If input value is in dd-mmm-yy format, then reformat.
|
159
|
-
# Otherwise, parse as a Date if possible.
|
160
|
-
if f =~ /^\d{1,2}-\w{3}-\d{2,4}$/ then
|
161
|
-
ddmmyy = reformat_dd_mmm_yy_date(f) || return
|
162
|
-
convert_date(ddmmyy)
|
163
|
-
# elsif f =~ /^\w{3} \d{1,2}, \d{4}$/ then
|
164
|
-
# ddmmyy = reformat_mmm_dd_yyyy_date(f) || return
|
165
|
-
# convert_date(ddmmyy)
|
166
|
-
else
|
167
|
-
Date.parse(f, true) rescue nil
|
142
|
+
|
143
|
+
alias :<< :write
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
# 3-letter months => month sequence hash.
|
148
|
+
MMM_MM_MAP = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'].to_compact_hash_with_index do |mmm, index|
|
149
|
+
index < 9 ? ('0' + index.succ.to_s) : index.succ.to_s
|
168
150
|
end
|
151
|
+
|
152
|
+
# DateMatcher relaxes the FasterCSV DateMatcher to allow dd/mm/yyyy dates.
|
153
|
+
DateMatcher = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} | \d{1,2}-\w{3}-\d{2,4} | \d{4}[-\/]\d{1,2}[-\/]\d{1,2} | \d{1,2}[-\/]\d{1,2}[-\/]\d{2,4} )\z /x
|
154
|
+
|
155
|
+
# @param f the input field value to convert
|
156
|
+
# @param info the CSV field info
|
157
|
+
# @return the converted value
|
158
|
+
def convert(f, info)
|
159
|
+
return if f.nil?
|
160
|
+
# the block has precedence
|
161
|
+
value = yield(f, info) if block_given?
|
162
|
+
# integer conversion
|
163
|
+
value ||= Integer(f) if f =~ /^[1-9]\d*$/
|
164
|
+
# date conversion
|
165
|
+
value ||= convert_date(f) if f =~ CsvIO::DateMatcher
|
166
|
+
# float conversion
|
167
|
+
value ||= (Float(f) rescue f) if f =~ /^\d+\.\d*$/ or f =~ /^\d*\.\d+$/
|
168
|
+
# return converted value or the input field if there was no conversion
|
169
|
+
value || f
|
170
|
+
end
|
171
|
+
|
172
|
+
# @param [String] the input field value
|
173
|
+
# @return [Date] the converted date
|
174
|
+
def convert_date(f)
|
175
|
+
# If input value is in dd-mmm-yy format, then reformat.
|
176
|
+
# Otherwise, parse as a Date if possible.
|
177
|
+
if f =~ /^\d{1,2}-\w{3}-\d{2,4}$/ then
|
178
|
+
ddmmyy = reformat_dd_mmm_yy_date(f) || return
|
179
|
+
convert_date(ddmmyy)
|
180
|
+
# elsif f =~ /^\w{3} \d{1,2}, \d{4}$/ then
|
181
|
+
# ddmmyy = reformat_mmm_dd_yyyy_date(f) || return
|
182
|
+
# convert_date(ddmmyy)
|
183
|
+
else
|
184
|
+
Date.parse(f, true) rescue nil
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# @param [String] the input field value in dd-mmm-yy format
|
189
|
+
# @return [String] the reformatted date String in mm/dd/yy format
|
190
|
+
def reformat_dd_mmm_yy_date(f)
|
191
|
+
all, dd, mmm, yy = /^(\d{1,2})-([[:alpha:]]{3})-(\d{2,4})$/.match(f).to_a
|
192
|
+
mm = MMM_MM_MAP[mmm.downcase] || return
|
193
|
+
"#{mm}/#{dd}/#{yy}"
|
194
|
+
end
|
195
|
+
# # @param [String] the input field value in 'mmmd d, yyyy' format
|
196
|
+
# # @return [String] the reformatted date String in mm/dd/yyyy format
|
197
|
+
# def reformat_mmm_dd_yyyy_date(f)
|
198
|
+
# all, mmm, dd, yyyy = /^(\w{3}) (\d{1,2}), (\d{4})$/.match(f).to_a
|
199
|
+
# mm = MMM_MM_MAP[mmm.downcase] || return
|
200
|
+
# "#{mm}/#{dd}/#{yyyy}"
|
201
|
+
# end
|
169
202
|
end
|
170
|
-
|
171
|
-
# @param [String] the input field value in dd-mmm-yy format
|
172
|
-
# @return [String] the reformatted date String in mm/dd/yy format
|
173
|
-
def reformat_dd_mmm_yy_date(f)
|
174
|
-
all, dd, mmm, yy = /^(\d{1,2})-([[:alpha:]]{3})-(\d{2,4})$/.match(f).to_a
|
175
|
-
mm = MMM_MM_MAP[mmm.downcase] || return
|
176
|
-
"#{mm}/#{dd}/#{yy}"
|
177
|
-
end
|
178
|
-
# # @param [String] the input field value in 'mmmd d, yyyy' format
|
179
|
-
# # @return [String] the reformatted date String in mm/dd/yyyy format
|
180
|
-
# def reformat_mmm_dd_yyyy_date(f)
|
181
|
-
# all, mmm, dd, yyyy = /^(\w{3}) (\d{1,2}), (\d{4})$/.match(f).to_a
|
182
|
-
# mm = MMM_MM_MAP[mmm.downcase] || return
|
183
|
-
# "#{mm}/#{dd}/#{yyyy}"
|
184
|
-
# end
|
185
203
|
end
|