db_suit_rails 0.4.1
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 +7 -0
- data/.gitignore +11 -0
- data/ChangeLog +41 -0
- data/Makefile +22 -0
- data/README.en.rdoc +118 -0
- data/Rakefile +9 -0
- data/bin/copy_nline +141 -0
- data/bin/mk_sqlskelton +158 -0
- data/db_suit_rails.gemspec +47 -0
- data/lib/db_suit_rails/db_suit_rails_error.rb +7 -0
- data/lib/db_suit_rails/sql_skelton.rb +1108 -0
- data/lib/db_suit_rails/sql_skelton/col_index.rb +435 -0
- data/lib/db_suit_rails/sql_skelton/fkey.rb +61 -0
- data/lib/db_suit_rails/sql_skelton/tbl_index.rb +310 -0
- data/lib/db_suit_rails/sql_skelton/utils.rb +56 -0
- data/test/sql_skelton/test_col_index.rb +224 -0
- data/test/sql_skelton/test_fkey.rb +48 -0
- data/test/sql_skelton/test_tbl_index.rb +145 -0
- data/test/test_sql_skelton.rb +245 -0
- metadata +83 -0
@@ -0,0 +1,310 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Author: M. Sakano (Wise Babel Ltd)
|
4
|
+
|
5
|
+
require 'active_support/all'
|
6
|
+
require 'db_suit_rails/sql_skelton/utils' # class SqlSkelton is defined.
|
7
|
+
require 'db_suit_rails/db_suit_rails_error'
|
8
|
+
|
9
|
+
# =class SqlSkelton::TblIndex
|
10
|
+
#
|
11
|
+
# ==Summary
|
12
|
+
#
|
13
|
+
# Class for mapping between the original and modified SQL tables
|
14
|
+
#
|
15
|
+
# ==Description
|
16
|
+
#
|
17
|
+
# This holds the information of old and new names for each table.
|
18
|
+
#
|
19
|
+
# When you specify something, it is always the old table name.
|
20
|
+
#
|
21
|
+
# ==Example
|
22
|
+
#
|
23
|
+
# ci = SqlSkelton::TblIndex.new(tables) # Columns are not set.
|
24
|
+
# ci.update!(tables[0])
|
25
|
+
# ci.update!(:all)
|
26
|
+
#
|
27
|
+
# # Manually sets
|
28
|
+
# ci.set_newtblval_with(oldtbl, new_value)
|
29
|
+
# new_tbl_name = newtblval(oldtbl)
|
30
|
+
#
|
31
|
+
class SqlSkelton::TblIndex
|
32
|
+
|
33
|
+
# Constant SuffixId is defined.
|
34
|
+
include Object.const_get(parent_name)::Utils # parent_name defined in active_support/all
|
35
|
+
|
36
|
+
# REgular expression for TaBLe for RESerVeD SUFFIXes.
|
37
|
+
ReTblResvdSuffix = /(_id_seq|_pkey|_?unique)$/
|
38
|
+
|
39
|
+
# Hash:
|
40
|
+
# { Old-Table-Name => New-Table-Name }
|
41
|
+
attr_reader :tblmaps
|
42
|
+
|
43
|
+
# Constructor
|
44
|
+
#
|
45
|
+
# Table list is NOT mandatory to specify.
|
46
|
+
#
|
47
|
+
# @param oldtbls [Array,String] Old table name(s)
|
48
|
+
def initialize(oldtbls=[])
|
49
|
+
@tblmaps = {}
|
50
|
+
|
51
|
+
# [oldtbls].flatten.each do |ec|
|
52
|
+
[oldtbls].flatten.map{|i| remove_sqlprefix(i)}.uniq.each do |ec|
|
53
|
+
push(ec)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Whether empty
|
58
|
+
#
|
59
|
+
def empty?()
|
60
|
+
@tblmaps.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
# Whether a old-name table is registered?
|
64
|
+
#
|
65
|
+
# @param oldtbl [String] Old table name
|
66
|
+
def table_exist?(oldtbl)
|
67
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
68
|
+
@tblmaps.has_key?(oldtbl)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Gets a stored newtbl name
|
72
|
+
#
|
73
|
+
# @param oldtbl [String] Old table name
|
74
|
+
# @return [String] Stored new table name
|
75
|
+
def newtblval(oldtbl)
|
76
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
77
|
+
table_exist?(oldtbl) || (raise DbSuitRailsError, "ERROR: old-table (#{oldtbl}) is not registered.")
|
78
|
+
@tblmaps[oldtbl]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Sets a newtbl name
|
82
|
+
#
|
83
|
+
# @param oldtbl [String] Old table name
|
84
|
+
# @param value [String] new table name to set
|
85
|
+
# @return [String] Stored new table name
|
86
|
+
def set_newtblval_with(oldtbl, value)
|
87
|
+
# @tblmaps[oldtbl] = value
|
88
|
+
@tblmaps[remove_sqlprefix(oldtbl)] = remove_sqlprefix(value)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Push a new table
|
92
|
+
#
|
93
|
+
# Make sure to use this method to add a record in @tblmaps .
|
94
|
+
# Or, alternatively, you can use {#update!}, which calls this method,
|
95
|
+
# and sets newtbl automatically.
|
96
|
+
#
|
97
|
+
# If the record already exists, this raises an error.
|
98
|
+
#
|
99
|
+
# @param oldtbl [String] Old table name
|
100
|
+
# @param newtbl [String] New table name
|
101
|
+
# @return [self]
|
102
|
+
def push(oldtbl, newtbl=nil)
|
103
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
104
|
+
if table_exist?(oldtbl)
|
105
|
+
raise DbSuitRailsError, "ERROR: Failed to push old-table (#{oldtbl}) as it already exists."
|
106
|
+
else
|
107
|
+
if (oldtbl == :all) || (newtbl == :all)
|
108
|
+
raise DbSuitRailsError, "ERROR: :all is not allowed in push()."
|
109
|
+
end
|
110
|
+
@tblmaps[oldtbl] = remove_sqlprefix(newtbl)
|
111
|
+
end
|
112
|
+
|
113
|
+
self
|
114
|
+
end
|
115
|
+
|
116
|
+
# Update a table entry (or all the table entries) according to the rule
|
117
|
+
#
|
118
|
+
# If oldtbl is :all, all the tables are updated.
|
119
|
+
#
|
120
|
+
# This updates a newtbl name only
|
121
|
+
# if the existing one is empty or nil.
|
122
|
+
#
|
123
|
+
# If force: option is true, regardless of current newtbl name,
|
124
|
+
# newtbl is updated.
|
125
|
+
#
|
126
|
+
# To manually set the new table name, use {#set_newtblval_with}
|
127
|
+
#
|
128
|
+
# @param oldtbl [String, Symbol] Old table name or :all
|
129
|
+
# @param force forcibly updates.
|
130
|
+
# @return [self]
|
131
|
+
def update(oldtbl=:all, force: false)
|
132
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
133
|
+
if :all == oldtbl
|
134
|
+
oldtblnames().each do |ec_tbl|
|
135
|
+
update(ec_tbl, force: force)
|
136
|
+
end
|
137
|
+
return self
|
138
|
+
end
|
139
|
+
|
140
|
+
table_exist?(oldtbl) || (raise DbSuitRailsError, "ERROR: Failed to update old-table (#{oldtbl}), which is not registered.")
|
141
|
+
|
142
|
+
newtbl = newtblval(oldtbl)
|
143
|
+
if !newtbl || newtbl.empty?
|
144
|
+
set_newtblval_with(oldtbl, mk_newtblname(oldtbl))
|
145
|
+
end
|
146
|
+
|
147
|
+
## If force, attempts to update newtbl name regardless the other conditions.
|
148
|
+
force && set_newtblval_with(oldtbl, mk_newtblname(oldtbl))
|
149
|
+
|
150
|
+
return self
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
# Updates a table or pushes it if it is not registered, yet.
|
155
|
+
#
|
156
|
+
# Basically, this method is a wrapper for {#update} and {#push}
|
157
|
+
#
|
158
|
+
# This updates a newtbl name regardless the conditions (force option is set).
|
159
|
+
#
|
160
|
+
# If oldtbl is :all, all the table are updated, in which case
|
161
|
+
# fkey option is ignored.
|
162
|
+
#
|
163
|
+
# @param oldtbl [String, Symbol] Old table name or :all
|
164
|
+
# @return [self]
|
165
|
+
#
|
166
|
+
# @see SqlSkelton::TblIndex.update
|
167
|
+
def update!(oldtbl=:all)
|
168
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
169
|
+
if defined? oldtbl.gsub
|
170
|
+
table_exist?(oldtbl) || push(oldtbl)
|
171
|
+
end
|
172
|
+
return update(oldtbl, force: true)
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
# Wrapper of {#update!}
|
177
|
+
#
|
178
|
+
# It returns the new tablename.
|
179
|
+
# Also, it does NOT update the record, if the new file is already registered.
|
180
|
+
#
|
181
|
+
# @param oldtbl [String] Old table name
|
182
|
+
# @return [String]
|
183
|
+
#
|
184
|
+
# @see SqlSkelton::TblIndex.update!
|
185
|
+
def updated_tbl!(oldtbl)
|
186
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
187
|
+
if ! table_exist?(oldtbl)
|
188
|
+
push(oldtbl)
|
189
|
+
update(oldtbl, force: true)
|
190
|
+
end
|
191
|
+
newtblval(oldtbl)
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
# Returns an Array of old table names.
|
196
|
+
#
|
197
|
+
# @param exclude [String] Old table name, the corresponding value of which either becomes nil in, or if compact option is true, is excluded from, the result.
|
198
|
+
# @param compact [Boolean] Read only when exclude option is non-nil. If true (Def), the result is compacted; else the excluded value becomes nil.
|
199
|
+
# @return [Array[Hash]]
|
200
|
+
def oldtblnames(exclude: nil, compact: true)
|
201
|
+
old_or_newtblnames(:old, exclude: exclude, compact: compact)
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
# Returns an Array of new table names.
|
206
|
+
#
|
207
|
+
# @param (see #oldtblnames)
|
208
|
+
def newtblnames(exclude: nil, compact: true)
|
209
|
+
old_or_newtblnames(:new, exclude: exclude, compact: compact)
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
# Returns an Array of mixed table names == (new OR old)
|
214
|
+
#
|
215
|
+
# @param (see #oldtblnames)
|
216
|
+
def mixtblnames(exclude: nil, compact: true)
|
217
|
+
newtbl = newtblnames(exclude: exclude, compact: compact).map{|i| remove_sqlprefix(i)}
|
218
|
+
oldtbl = oldtblnames(exclude: exclude, compact: compact).map{|i| remove_sqlprefix(i)}
|
219
|
+
|
220
|
+
mixtbl = []
|
221
|
+
newtbl.each_with_index do |newc, i|
|
222
|
+
mixtbl[i] = (newc || oldtbl[i])
|
223
|
+
end
|
224
|
+
mixtbl
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
#######################################################
|
229
|
+
private
|
230
|
+
#######################################################
|
231
|
+
|
232
|
+
# Gets a non-existing new table name
|
233
|
+
#
|
234
|
+
# This is a low-level method,
|
235
|
+
# In practice, use {#update!} etc.
|
236
|
+
#
|
237
|
+
# At the moment no potential name crush is resolved.
|
238
|
+
# If you want to implement it, refer to in col_index.rb
|
239
|
+
#
|
240
|
+
# unique_colname()
|
241
|
+
#
|
242
|
+
# where a sequential trial is implemented.
|
243
|
+
# Note in the case of tables, there may be more than one table name
|
244
|
+
# related to a table, like `XXX_id_seq`. Hence if you change one,
|
245
|
+
# you should change all the related table names at the same time.
|
246
|
+
#
|
247
|
+
# @param oldtbl [String] Old table name
|
248
|
+
# @param useprefix [Boolean] If true, add a prefix as opposed to suffix.
|
249
|
+
# @return [String] Unique new table name
|
250
|
+
def mk_newtblname(oldtbl, useprefix: false)
|
251
|
+
oldtbl = remove_sqlprefix(oldtbl)
|
252
|
+
existing_tables = mixtblnames(exclude: oldtbl)
|
253
|
+
|
254
|
+
matched = ReTblResvdSuffix.match(oldtbl)
|
255
|
+
newtbl_root = (matched ? matched.pre_match : oldtbl)
|
256
|
+
|
257
|
+
## NOTE: The format *_[0-9]* for a table name is inconvenient.
|
258
|
+
## Therefore, it is converted into '*_n[0-9]*'
|
259
|
+
## singularize defined in active_support/all library
|
260
|
+
newtbl_root = ((/_\d/ =~ newtbl_root) ? newtbl_root.gsub(/_(\d)/, '_n\1') : newtbl_root).singularize
|
261
|
+
|
262
|
+
begin
|
263
|
+
# Singularized table name should not coincides with any existing constant names,
|
264
|
+
# be it Class name or existing Constant like Pi (if it does).
|
265
|
+
# If it does, the following raises NameError
|
266
|
+
# Note the table name "stdout" is OK, because the standard constant is STDOUT and is not Stdout.
|
267
|
+
# Note: to judge if it agrees with an existinc class but other constants,
|
268
|
+
# (Class == newtbl_root.classify.constantize.class)
|
269
|
+
newtbl_root.classify.constantize
|
270
|
+
newtbl_root += SuffixId
|
271
|
+
rescue NameError
|
272
|
+
end
|
273
|
+
|
274
|
+
# unique_name_cand defined in Utils module.
|
275
|
+
newtbl_root = unique_name_cand(newtbl_root, useprefix: useprefix){ |cand|
|
276
|
+
! existing_tables.include?( cand.pluralize + (matched ? matched[1] : '') )
|
277
|
+
}
|
278
|
+
|
279
|
+
if ! newtbl_root
|
280
|
+
raise DbSuitRailsError, "ERROR: new table name (#{oldtbl}) already exists. Consult the code developer."
|
281
|
+
end
|
282
|
+
|
283
|
+
newtbl_root.pluralize + (matched ? matched[1] : '')
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
# Core routine for {#oldtblnames} and {#newtblnames}
|
288
|
+
#
|
289
|
+
# @param old_or_new [Symbol] :old or :new.
|
290
|
+
# @param (see #oldtblnames)
|
291
|
+
# @return [Array]
|
292
|
+
def old_or_newtblnames(old_or_new, exclude: nil, compact: true)
|
293
|
+
arold = @tblmaps.keys
|
294
|
+
case old_or_new
|
295
|
+
when :old
|
296
|
+
arret = arold
|
297
|
+
when :new
|
298
|
+
arret = @tblmaps.values
|
299
|
+
else
|
300
|
+
raise
|
301
|
+
end
|
302
|
+
|
303
|
+
exclude || (return arret)
|
304
|
+
|
305
|
+
i = arold.find_index{ |val| exclude == val }
|
306
|
+
compact ? arret.delete_at(i) : (arret[i] = nil)
|
307
|
+
|
308
|
+
arret
|
309
|
+
end
|
310
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Author: M. Sakano (Wise Babel Ltd)
|
4
|
+
|
5
|
+
class SqlSkelton
|
6
|
+
|
7
|
+
# =module SqlSkelton::SuffixId
|
8
|
+
#
|
9
|
+
# ==Summary
|
10
|
+
#
|
11
|
+
# Module to define the constant {SqlSkelton::SuffixId::SuffixId}
|
12
|
+
# and other common functions.
|
13
|
+
#
|
14
|
+
module Utils
|
15
|
+
# Suffix to append to an "id"-type column name (in "client"-DBs).
|
16
|
+
SuffixId = '_cli'
|
17
|
+
|
18
|
+
#######################################################
|
19
|
+
private
|
20
|
+
#######################################################
|
21
|
+
|
22
|
+
# Returns a unique new table/column name.
|
23
|
+
#
|
24
|
+
# If the CANDIDATE is accepted, returns it.
|
25
|
+
# Else it searches for CANDIDATE1, CANDIDATE2, ... etc.
|
26
|
+
# Or, n1_CANDIDATE, n2_CANDIDATE1, ... etc, if useprefix option is true.
|
27
|
+
#
|
28
|
+
# This method yields a block, where a candidate name is given and true should be returned when accepted.
|
29
|
+
#
|
30
|
+
# @param name_root [String, NilClass] Candidate new column name. If unspecified, copied from oldcol
|
31
|
+
# @param useprefix [Boolean] If true, add a prefix as opposed to suffix.
|
32
|
+
# @yield [name_cand] Candidate name is passed to the block. It should return true if the name is OK.
|
33
|
+
# @yieldparam [name_cand, String] Candidate name
|
34
|
+
# @yieldreturn [String, NilClass] Candidate name if found, else nil.
|
35
|
+
# @return [String, NilClass] Unique new column name
|
36
|
+
def unique_name_cand(name_root, useprefix: false)
|
37
|
+
yield(name_root) && (return name_root)
|
38
|
+
(1..99999).each do |i|
|
39
|
+
name_cand = (useprefix ? sprintf('n%d_%s', i, name_root) : sprintf('%s%d', name_root, i))
|
40
|
+
yield(name_cand) && (return name_cand)
|
41
|
+
end
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Remove the 'public.' prefix for the table (for the internal use)
|
47
|
+
#
|
48
|
+
# @param tblname [String] Table name
|
49
|
+
# @return [String]
|
50
|
+
def remove_sqlprefix(tblname)
|
51
|
+
return tblname if !defined?(tblname.gsub)
|
52
|
+
tblname = tblname.sub(/^public\./, '')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Author: M. Sakano (Wise Babel Ltd)
|
4
|
+
|
5
|
+
require 'db_suit_rails/sql_skelton/col_index'
|
6
|
+
|
7
|
+
$stdout.sync=true
|
8
|
+
$stderr.sync=true
|
9
|
+
|
10
|
+
#################################################
|
11
|
+
# Unit Test
|
12
|
+
#################################################
|
13
|
+
|
14
|
+
#if $0 == __FILE__
|
15
|
+
gem "minitest"
|
16
|
+
# require 'minitest/unit'
|
17
|
+
require 'minitest/autorun'
|
18
|
+
# MiniTest::Unit.autorun
|
19
|
+
|
20
|
+
class TestUnitSqlSkeltonColIndex < MiniTest::Test
|
21
|
+
T = true
|
22
|
+
F = false
|
23
|
+
SCFNAME = File.basename(__FILE__)
|
24
|
+
CI = SqlSkelton::ColIndex
|
25
|
+
|
26
|
+
def setup
|
27
|
+
# @ib = 1
|
28
|
+
end
|
29
|
+
# teardown is not often used.
|
30
|
+
def teardown
|
31
|
+
# @foo = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def test_initialize01
|
36
|
+
c1 = CI.new('tblold')
|
37
|
+
assert_equal ['tblold'], c1.colmaps.keys
|
38
|
+
c2 = CI.new(['tblold'])
|
39
|
+
assert_equal ['tblold'], c2.colmaps.keys
|
40
|
+
c3 = CI.new()
|
41
|
+
c3.push('tblold')
|
42
|
+
assert_equal ['tblold'], c3.colmaps.keys
|
43
|
+
c3.push('tblold2')
|
44
|
+
assert_equal %w(tblold tblold2), c3.colmaps.keys
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_push01
|
48
|
+
oldtbl = 'tblold1'
|
49
|
+
oldcol = 'tblcol1'
|
50
|
+
ci = CI.new(oldtbl)
|
51
|
+
assert_raises(DbSuitRailsError){ ci.push(oldtbl) }
|
52
|
+
ci.push(oldtbl, oldcol, 'atai')
|
53
|
+
assert_raises(DbSuitRailsError){ ci.push(oldtbl, oldcol) }
|
54
|
+
|
55
|
+
assert ci.table_exist?(oldtbl)
|
56
|
+
assert ci.column_registered?(oldtbl, oldcol)
|
57
|
+
assert !ci.table_exist?('naiyo')
|
58
|
+
assert !ci.column_registered?('naiyo', oldcol)
|
59
|
+
assert !ci.column_registered?(oldtbl, 'naiyo')
|
60
|
+
|
61
|
+
assert_equal 'atai', ci.newcolval(oldtbl, oldcol)
|
62
|
+
ci.set_newcolval_with(oldtbl, oldcol, nil)
|
63
|
+
assert_nil ci.newcolval(oldtbl, oldcol)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_fkey01
|
67
|
+
oldtbl = 'tblold1'
|
68
|
+
oldcol = 'tblcol1'
|
69
|
+
ci = CI.new(oldtbl)
|
70
|
+
assert !ci.fkey?(oldtbl, oldcol)
|
71
|
+
|
72
|
+
ci.push(oldtbl, oldcol, fkey: true)
|
73
|
+
assert ci.fkey?(oldtbl, oldcol)
|
74
|
+
assert_equal true, ci.fkeyval(oldtbl, oldcol)
|
75
|
+
|
76
|
+
ci.set_fkeyval_with(oldtbl, oldcol, nil)
|
77
|
+
assert !ci.fkey?(oldtbl, oldcol)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_update01
|
81
|
+
oldtbls = %w(tblold1 tblold2 tblold3)
|
82
|
+
oldcols = %w(colold1 colold2 colold21)
|
83
|
+
ci = CI.new(oldtbls[0])
|
84
|
+
|
85
|
+
ci.push(oldtbls[0], oldcols[0])
|
86
|
+
ci.push(oldtbls[0], oldcols[1])
|
87
|
+
|
88
|
+
assert_raises(DbSuitRailsError){ ci.paircolnames('naiyo') }
|
89
|
+
assert_equal oldcols[0..1], ci.oldcolnames(oldtbls[0])
|
90
|
+
|
91
|
+
assert_raises(DbSuitRailsError){ ci.update(oldtbls[1], oldcols[0]) }
|
92
|
+
assert_raises(DbSuitRailsError){ ci.update(oldtbls[0], oldcols[2]) }
|
93
|
+
|
94
|
+
assert_nil ci.newcolval(oldtbls[0], oldcols[0])
|
95
|
+
ci.update(oldtbls[0], oldcols[0])
|
96
|
+
assert_equal oldcols[0], ci.newcolval(oldtbls[0], oldcols[0])
|
97
|
+
|
98
|
+
# Test update!() - wrapper of push()
|
99
|
+
ci.update!(oldtbls[0], oldcols[2])
|
100
|
+
assert_equal oldcols, ci.oldcolnames(oldtbls[0])
|
101
|
+
assert_equal oldcols[2], ci.newcolval(oldtbls[0], oldcols[2])
|
102
|
+
ci.update!(oldtbls[2], oldcols[0]) # Push for new table.
|
103
|
+
|
104
|
+
# Test update!() - wrapper of update()
|
105
|
+
ci.update!(oldtbls[0], oldcols[1])
|
106
|
+
assert_equal oldcols[1], ci.newcolval(oldtbls[0], oldcols[1])
|
107
|
+
# Test newcolnames()
|
108
|
+
assert_equal oldcols, ci.newcolnames(oldtbls[0])
|
109
|
+
|
110
|
+
# Test unique_colname
|
111
|
+
assert_equal 'n1_'+oldcols[1], ci.instance_eval{ unique_colname(oldtbls[0], oldcols[0], oldcols[1], useprefix: true) }
|
112
|
+
assert_equal oldcols[1]+'2', ci.instance_eval{ unique_colname(oldtbls[0], oldcols[0], oldcols[1], useprefix: false) }
|
113
|
+
assert_equal oldcols[1], ci.instance_eval{ unique_colname(oldtbls[0], oldcols[1], useprefix: false) }
|
114
|
+
# Reserved words: 'type' => 'type_cli', 'MyTable_count' => 'MyTable_count_cli'
|
115
|
+
['type', oldtbls[0]+'count'].each do |i|
|
116
|
+
ci.push(oldtbls[0], i)
|
117
|
+
assert_equal i+'_cli', ci.instance_eval{ unique_colname(oldtbls[0], i, useprefix: false) }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def test_newcolnames01
|
123
|
+
oldtbls = %w(tblold1 tblprt2 tblprt3)
|
124
|
+
oldcols = %w(id non_id non_id_cli job_id normal)
|
125
|
+
ci = CI.new(oldtbls)
|
126
|
+
oldtbl = oldtbls[0]
|
127
|
+
oldcols.each do |ec|
|
128
|
+
ci.push(oldtbl, ec, ec)
|
129
|
+
end
|
130
|
+
assert_equal oldcols, ci.newcolnames(oldtbl)
|
131
|
+
assert_equal [nil]+oldcols[1..-1], ci.newcolnames(oldtbl, exclude: 'id', compact: false)
|
132
|
+
assert_equal oldcols[1..-1], ci.newcolnames(oldtbl, exclude: 'id', compact: true)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_mk_newcolname01
|
136
|
+
oldtbls = %w(tblold1 tblprt2 tblprt3)
|
137
|
+
oldcols = %w(id non_id non_id_cli job_id normal)
|
138
|
+
ci = CI.new(oldtbls)
|
139
|
+
|
140
|
+
oldtbl = oldtbls[0]
|
141
|
+
oldcols.each do |ec|
|
142
|
+
ci.push(oldtbl, ec, ec)
|
143
|
+
end
|
144
|
+
assert_equal oldcols, ci.newcolnames(oldtbl)
|
145
|
+
assert_equal 'non_id_cli1', ci.instance_eval{ mk_newcolname(oldtbl, oldcols[1]) }
|
146
|
+
|
147
|
+
ci.update(oldtbl, oldcols[1])
|
148
|
+
## update does nothing, because everything is already set and fkey is nil.
|
149
|
+
assert_equal oldcols, ci.newcolnames(oldtbl)
|
150
|
+
assert( 'non_id_cli1' != ci.newcolval(oldtbl, oldcols[1]))
|
151
|
+
|
152
|
+
## force option
|
153
|
+
ci.update(oldtbl, oldcols[1], force: true)
|
154
|
+
assert_equal 'non_id_cli1', ci.newcolval(oldtbl, oldcols[1])
|
155
|
+
|
156
|
+
## update!
|
157
|
+
ci.update( oldtbl, oldcols[3])
|
158
|
+
assert( 'job_id_cli' != ci.newcolval(oldtbl, oldcols[3]))
|
159
|
+
ci.update!(oldtbl, oldcols[3])
|
160
|
+
assert_equal 'job_id_cli', ci.newcolval(oldtbl, oldcols[3])
|
161
|
+
|
162
|
+
## update! with :all
|
163
|
+
assert( 'id_cli' != ci.newcolval(oldtbl, oldcols[0]))
|
164
|
+
ci.update!(oldtbl, :all)
|
165
|
+
assert( 'id_cli' == ci.newcolval(oldtbl, oldcols[0]))
|
166
|
+
assert_equal 'id_cli', ci.newcolval(oldtbl, oldcols[0])
|
167
|
+
assert_equal 'job_id_cli', ci.newcolval(oldtbl, oldcols[3]) # unchanged
|
168
|
+
# p ci.newcolnames(oldtbl)
|
169
|
+
# => ["id_cli", "non_id_cli2", "non_id_cli", "job_id_cli1", "normal"]
|
170
|
+
|
171
|
+
## update! with fkey is set
|
172
|
+
fk_job = SqlSkelton::Fkey.new('tblold1', oldcols[3], 'tblprt2', 'eid')
|
173
|
+
ci.set_fkeyval_with(oldtbl, oldcols[3], fk_job)
|
174
|
+
assert_equal 'job_id', ci.instance_eval{ mk_newcolname(oldtbl, oldcols[3]) }
|
175
|
+
|
176
|
+
assert_equal 'job_id_cli', ci.newcolval(oldtbl, oldcols[3])
|
177
|
+
ci.update(oldtbl, oldcols[3], fkey: fk_job)
|
178
|
+
assert_equal 'job_id', ci.newcolval(oldtbl, oldcols[3])
|
179
|
+
|
180
|
+
## Is non_id_cli1 reversed if fkey is set?
|
181
|
+
fk_non = SqlSkelton::Fkey.new('tblold1', oldcols[1], 'tblprt2', 'eid')
|
182
|
+
assert_equal 'non_id_cli1', ci.newcolval(oldtbl, oldcols[1])
|
183
|
+
ci.update!(oldtbl, oldcols[1], fkey: fk_non)
|
184
|
+
assert_equal 'non_id', ci.newcolval(oldtbl, oldcols[1])
|
185
|
+
|
186
|
+
## Is id properly set if fkey is set?
|
187
|
+
fk_id = SqlSkelton::Fkey.new('tblold1', oldcols[0], 'tblprt2', 'eid')
|
188
|
+
assert_equal 'id_cli', ci.newcolval(oldtbl, oldcols[0])
|
189
|
+
ci.update!(oldtbl, oldcols[0], fkey: fk_id)
|
190
|
+
assert_equal 'id_cli_id', ci.newcolval(oldtbl, oldcols[0])
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_updated_col01
|
194
|
+
oldtbls = %w(tblold1 tblprt2 tblprt3)
|
195
|
+
oldcols = %w(id non_id non_id_cli job_id normal)
|
196
|
+
ci = CI.new()
|
197
|
+
|
198
|
+
assert_equal 'id_cli', ci.updated_col!(oldtbls[0], oldcols[0])
|
199
|
+
|
200
|
+
## updated_col! not updates if the record exists.
|
201
|
+
ci.push(oldtbls[0], oldcols[3])
|
202
|
+
assert( 'job_id_cli' != ci.updated_col!(oldtbls[0], oldcols[3]))
|
203
|
+
|
204
|
+
## update! does update.
|
205
|
+
ci.update!(oldtbls[0], oldcols[3])
|
206
|
+
assert_equal 'job_id_cli', ci.updated_col!(oldtbls[0], oldcols[3])
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_update02
|
210
|
+
ci = CI.new()
|
211
|
+
hs = {"reha_b01"=>{:order=>["id", "tax_id"], "id"=>{:name=>"id_cli", :fkey=>nil}, "tax_id"=>{:name=>"tax_id_cli", :fkey=>nil}}}
|
212
|
+
ci.instance_eval{ @colmaps = hs }
|
213
|
+
fk_now = SqlSkelton::Fkey.new("reha_b01", 'tax_id', "tax_table", "vat_id")
|
214
|
+
|
215
|
+
ci.update!("reha_b01", nil, fkey: nil) # fkey: fk_now would issues a WARNING as expected.
|
216
|
+
assert_equal hs, ci.colmaps
|
217
|
+
|
218
|
+
ci.update!("reha_b01", 'id_cli', fkey: fk_now)
|
219
|
+
end
|
220
|
+
end # class TestUnitSqlSkeltonColIndex < MiniTest::Test
|
221
|
+
|
222
|
+
#end # if $0 == __FILE__
|
223
|
+
|
224
|
+
|