transactd 2.4.5-x86-mswin32-100 → 3.0.0-x86-mswin32-100

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,748 @@
1
+ # coding : utf-8
2
+ =begin ============================================================
3
+ Copyright (C) 2015 BizStation Corp All rights reserved.
4
+
5
+ This program is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU General Public License
7
+ as published by the Free Software Foundation; either version 2
8
+ of the License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18
+ 02111-1307, USA.
19
+ ===================================================================
20
+ =end
21
+ require 'transactd'
22
+
23
+ require 'rbconfig'
24
+ IS_WINDOWS = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
25
+
26
+ def getEnv(valuename)
27
+ return ENV[valuename] if ENV[valuename] != nil
28
+ return ''
29
+ end
30
+
31
+ def getHost()
32
+ hostname = getEnv('TRANSACTD_RSPEC_HOST')
33
+ hostname = '127.0.0.1/' if hostname == ''
34
+ hostname = hostname + '/' unless (hostname =~ /\/$/)
35
+ return hostname
36
+ end
37
+
38
+ HOSTNAME = getHost()
39
+ USERNAME = getEnv('TRANSACTD_RSPEC_USER')
40
+ USERPART = USERNAME == '' ? '' : USERNAME + '@'
41
+ PASSWORD = getEnv('TRANSACTD_RSPEC_PASS')
42
+ PASSPART = PASSWORD == '' ? '' : '&pwd=' + PASSWORD
43
+ PASSPART2 = PASSWORD == '' ? '' : '?pwd=' + PASSWORD
44
+ DBNAME = 'test_v3'
45
+ TABLENAME = 'user'
46
+ PROTOCOL = 'tdap://'
47
+ BDFNAME = '?dbfile=test.bdf'
48
+ URL = PROTOCOL + USERPART + HOSTNAME + DBNAME + BDFNAME + PASSPART
49
+ URL_AUTOSCHEMA = PROTOCOL + USERPART + HOSTNAME + DBNAME + PASSPART2
50
+
51
+ SEB_TABLENAME = "setenumbit"
52
+ CREATE_SEB_TABLE_SQL = <<'EOS'
53
+ CREATE TABLE `setenumbit` (
54
+ `id` int(11) NOT NULL AUTO_INCREMENT,
55
+ `set5` set('A','B','C','D','E') DEFAULT '',
56
+ `set64` set('a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9',
57
+ 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9',
58
+ 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9',
59
+ 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9',
60
+ 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9',
61
+ 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9',
62
+ 'g0', 'g1', 'g2', 'g3') DEFAULT '',
63
+ `enum2` enum('Y','N') DEFAULT 'N',
64
+ `enum260` enum('a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9',
65
+ 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9',
66
+ 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9',
67
+ 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9',
68
+ 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9',
69
+ 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9',
70
+ 'g0', 'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'g9',
71
+ 'h0', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'h9',
72
+ 'i0', 'i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8', 'i9',
73
+ 'j0', 'j1', 'j2', 'j3', 'j4', 'j5', 'j6', 'j7', 'j8', 'j9',
74
+ 'k0', 'k1', 'k2', 'k3', 'k4', 'k5', 'k6', 'k7', 'k8', 'k9',
75
+ 'l0', 'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8', 'l9',
76
+ 'm0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9',
77
+ 'n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9',
78
+ 'o0', 'o1', 'o2', 'o3', 'o4', 'o5', 'o6', 'o7', 'o8', 'o9',
79
+ 'p0', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9',
80
+ 'q0', 'q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9',
81
+ 'r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9',
82
+ 's0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9',
83
+ 't0', 't1', 't2', 't3', 't4', 't5', 't6', 't7', 't8', 't9',
84
+ 'u0', 'u1', 'u2', 'u3', 'u4', 'u5', 'u6', 'u7', 'u8', 'u9',
85
+ 'v0', 'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8', 'v9',
86
+ 'w0', 'w1', 'w2', 'w3', 'w4', 'w5', 'w6', 'w7', 'w8', 'w9',
87
+ 'x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9',
88
+ 'y0', 'y1', 'y2', 'y3', 'y4', 'y5', 'y6', 'y7', 'y8', 'y9',
89
+ 'z0', 'z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8', 'z9') DEFAULT 'a0',
90
+ `bit1` bit(1) DEFAULT b'0',
91
+ `bit8` bit(8) DEFAULT b'0',
92
+ `bit32` bit(32) DEFAULT b'0',
93
+ `bit64` bit(64) DEFAULT b'0',
94
+ PRIMARY KEY (`id`)
95
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
96
+ EOS
97
+ INSERT_SEB_TABLE_SQL = <<'EOS'
98
+ INSERT INTO `setenumbit` (`id`, `set5`, `set64`, `enum2`, `enum260`, `bit1`, `bit8`, `bit32`, `bit64`) VALUES
99
+ (1, 'A', 'a0', 'N', 'a0', b'1', b'1', b'1', b'1'),
100
+ (2, 'A,B,C,D,E', 'a0,g3', 'Y', 'z9', b'1', b'11111111',
101
+ b'11111111111111111111111111111111',
102
+ b'1111111111111111111111111111111111111111111111111111111111111111'),
103
+ (3, '', '', '0', '0', b'0', b'00000000', b'00000000', b'00000000'),
104
+ (4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
105
+ (5, '', 'a0,g1', 'N', 'a0', b'1', b'1', b'1',
106
+ b'0011111111111111111111111111111111111111111111111111111111111111'),
107
+ (6, '', 'a0,g2', 'N', 'a0', b'1', b'1', b'1',
108
+ b'0111111111111111111111111111111111111111111111111111111111111111'),
109
+ (7, '', 'g3', 'N', 'a0', b'1', b'1', b'1',
110
+ b'1000000000000000000000000000000000000000000000000000000000000000');
111
+ EOS
112
+
113
+ def dropDatabase(db)
114
+ db.open(URL)
115
+ expect(db.stat()).to eq 0
116
+ db.drop()
117
+ expect(db.stat()).to eq 0
118
+ end
119
+
120
+ def createDatabase(db)
121
+ db.create(URL)
122
+ if (db.stat() == Transactd::STATUS_TABLE_EXISTS_ERROR)
123
+ dropDatabase(db)
124
+ db.create(URL)
125
+ end
126
+ expect(db.stat()).to eq 0
127
+ end
128
+
129
+ def openDatabase(db)
130
+ return db.open(URL, Transactd::TYPE_SCHEMA_BDF, Transactd::TD_OPEN_NORMAL)
131
+ end
132
+
133
+ def openDatabaseAutoSchema(db)
134
+ return db.open(URL_AUTOSCHEMA, Transactd::TYPE_SCHEMA_BDF, Transactd::TD_OPEN_NORMAL)
135
+ end
136
+
137
+ def isMySQL5_5(db)
138
+ vv = Transactd::BtrVersions.new()
139
+ db.getBtrVersion(vv)
140
+ server_ver = vv.version(1)
141
+ return (db.stat() == 0) &&
142
+ (5 == server_ver.majorVersion) &&
143
+ (5 == server_ver.minorVersion)
144
+ end
145
+
146
+ def isLegacyTimeFormat(db)
147
+ vv = Transactd::BtrVersions.new()
148
+ db.getBtrVersion(vv)
149
+ server_ver = vv.version(1)
150
+ return (db.stat() == 0) &&
151
+ (5 == server_ver.majorVersion) &&
152
+ (5 == server_ver.minorVersion) &&
153
+ (server_ver.type == Transactd::MYSQL_TYPE_MYSQL)
154
+ end
155
+
156
+ def createUserTable(db)
157
+ dbdef = db.dbDef()
158
+ expect(dbdef).not_to eq nil
159
+ td = Transactd::Tabledef.new()
160
+ td.schemaCodePage = Transactd::CP_UTF8
161
+ td.setTableName(TABLENAME)
162
+ td.setFileName(TABLENAME + '.dat')
163
+ td.charsetIndex = Transactd::CHARSET_UTF8
164
+ tableid = 1
165
+ td.id = tableid
166
+ td.pageSize = 2048
167
+ dbdef.insertTable(td)
168
+ expect(dbdef.stat()).to eq 0
169
+ fieldIndex = 0
170
+ fd = dbdef.insertField(tableid, fieldIndex)
171
+ fd.setName('id')
172
+ fd.type = Transactd::Ft_autoinc
173
+ fd.len = 4
174
+ fieldIndex += 1
175
+ fd = dbdef.insertField(tableid, fieldIndex)
176
+ fd.setName('名前')
177
+ fd.type = Transactd::Ft_myvarchar
178
+ fd.len = 2
179
+ expect(fd.isValidCharNum()).to eq false
180
+ fd.setLenByCharnum(20)
181
+ expect(fd.isValidCharNum()).to eq true
182
+ fd.setDefaultValue("John")
183
+ expect(fd.isPadCharType()).to eq false
184
+ expect(fd.isDateTimeType()).to eq false
185
+ fieldIndex += 1
186
+ fd = dbdef.insertField(tableid, fieldIndex)
187
+ fd.setName('group')
188
+ fd.type = Transactd::Ft_integer
189
+ fd.len = 4
190
+ fd.setNullable(true, false)
191
+ fd.setDefaultValue(10)
192
+ fieldIndex += 1
193
+ fd = dbdef.insertField(tableid, fieldIndex)
194
+ fd.setName('tel')
195
+ fd.type = Transactd::Ft_myvarchar
196
+ fd.len = 4
197
+ fd.setLenByCharnum(21)
198
+ fd.setNullable(true)
199
+ fieldIndex += 1
200
+ fd = dbdef.insertField(tableid, fieldIndex)
201
+ fd.setName('update_datetime')
202
+ fd.type = Transactd::Ft_mytimestamp
203
+ fd.len = 7
204
+ fd.setDefaultValue(Transactd::DFV_TIMESTAMP_DEFAULT)
205
+ fd.setTimeStampOnUpdate(true)
206
+ expect(fd.isTimeStampOnUpdate()).to eq true
207
+ fieldIndex += 1
208
+ fd = dbdef.insertField(tableid, fieldIndex)
209
+ fd.setName('create_datetime')
210
+ if (isMySQL5_5(db))
211
+ fd.type = Transactd::Ft_mydatetime
212
+ fd.len = 8
213
+ else
214
+ fd.type = Transactd::Ft_mytimestamp
215
+ fd.len = 4
216
+ fd.setDefaultValue(Transactd::DFV_TIMESTAMP_DEFAULT)
217
+ end
218
+ fd.setTimeStampOnUpdate(false)
219
+ expect(fd.isTimeStampOnUpdate()).to eq false
220
+ expect(fd.isPadCharType()).to eq false
221
+ expect(fd.isDateTimeType()).to eq true
222
+ keynum = 0
223
+ kd = dbdef.insertKey(tableid, keynum)
224
+ kd.segment(0).fieldNum = 0
225
+ kd.segment(0).flags.bit8 = 1
226
+ kd.segment(0).flags.bit1 = 1
227
+ kd.segmentCount = 1
228
+ td = dbdef.tableDefs(tableid)
229
+ td.primaryKeyNum = keynum
230
+ keynum += 1
231
+ kd = dbdef.insertKey(tableid, keynum)
232
+ kd.segment(0).fieldNum = 2
233
+ kd.segment(0).flags.bit0 = 1 # key_duplicate
234
+ kd.segment(0).flags.bit8 = 1
235
+ kd.segment(0).flags.bit1 = 1
236
+ kd.segmentCount = 1
237
+ dbdef.updateTableDef(tableid)
238
+ expect(dbdef.stat()).to eq 0
239
+ end
240
+
241
+ def createUserExtTable(db)
242
+ openDatabase(db)
243
+ dbdef = db.dbDef()
244
+ expect(dbdef).not_to eq nil
245
+ td = Transactd::Tabledef.new()
246
+ td.schemaCodePage = Transactd::CP_UTF8
247
+ td.setTableName("extention")
248
+ td.setFileName("extention")
249
+ td.charsetIndex = Transactd::CHARSET_UTF8
250
+ tableid = 2
251
+ td.id = tableid
252
+ dbdef.insertTable(td)
253
+ expect(dbdef.stat()).to eq 0
254
+ fieldIndex = 0
255
+ fd = dbdef.insertField(tableid, fieldIndex)
256
+ fd.setName('id')
257
+ fd.type = Transactd::Ft_integer
258
+ fd.len = 4
259
+ fieldIndex += 1
260
+ fd = dbdef.insertField(tableid, fieldIndex)
261
+ fd.setName('comment')
262
+ fd.type = Transactd::Ft_myvarchar
263
+ fd.setLenByCharnum(60)
264
+ fd.setNullable(true)
265
+ expect(fd.isDefaultNull()).to eq true
266
+ fieldIndex += 1
267
+ fd = dbdef.insertField(tableid, fieldIndex)
268
+ fd.setName('bits')
269
+ fd.type = Transactd::Ft_integer
270
+ fd.len = 8
271
+ expect(fd.isDefaultNull()).to eq false
272
+ keynum = 0
273
+ kd = dbdef.insertKey(tableid, keynum)
274
+ kd.segment(0).fieldNum = 0
275
+ kd.segment(0).flags.bit8 = 1
276
+ kd.segment(0).flags.bit1 = 1
277
+ kd.segmentCount = 1
278
+ td = dbdef.tableDefs(tableid)
279
+ td.primaryKeyNum = keynum
280
+ dbdef.updateTableDef(tableid)
281
+ expect(dbdef.stat()).to eq 0
282
+ end
283
+
284
+ def insertData(db)
285
+ tb = db.openTable("user", Transactd::TD_OPEN_NORMAL)
286
+ expect(db.stat()).to eq 0
287
+ tb3 = db.openTable("extention", Transactd::TD_OPEN_NORMAL)
288
+ expect(db.stat()).to eq 0
289
+ begin
290
+ db.beginTrn()
291
+ tb.clearBuffer()
292
+ for i in 1..1000
293
+ tb.setFV(0, i)
294
+ tb.setFV(1, i.to_s() + " user")
295
+ tb.setFV(2, ((i-1) % 5)+1)
296
+ tb.insert()
297
+ end
298
+ tb3.clearBuffer()
299
+ for i in 1..1000
300
+ tb3.setFV(0, i)
301
+ tb3.setFV(1, i.to_s() + " comment")
302
+ tb3.insert()
303
+ end
304
+ db.endTrn()
305
+ tb.close()
306
+ tb3.close()
307
+ rescue => e
308
+ db.abortTrn()
309
+ tb.close()
310
+ tb3.close()
311
+ expect(true).to eq false
312
+ end
313
+ end
314
+
315
+ def openTableOnce(db)
316
+ tb = db.openTable("user") # open table to get table schema information.
317
+ tb.close() # schema information is cached until db.close,
318
+ tb.release() # if table is closed and table object is released.
319
+ end
320
+
321
+ def createSetEnumBitTable(db)
322
+ tableid = 3
323
+ db.createTable(CREATE_SEB_TABLE_SQL) # RUN SQL
324
+ expect(db.stat()).to eq 0
325
+ db.createTable(INSERT_SEB_TABLE_SQL) # RUN SQL
326
+ expect(db.stat()).to eq 0
327
+ end
328
+
329
+ describe Transactd, 'V3Features' do
330
+ it 'create tables' do
331
+ db = Transactd::Database.new()
332
+ createDatabase(db)
333
+ openDatabase(db)
334
+ createUserTable(db)
335
+ createUserExtTable(db)
336
+ db.close()
337
+ end
338
+
339
+ it 'insert data' do
340
+ db = Transactd::Database.new()
341
+ openDatabase(db)
342
+ insertData(db)
343
+ db.close()
344
+ end
345
+
346
+ it 'set mode' do
347
+ db = Transactd::Database.new()
348
+ openDatabase(db)
349
+ db.setAutoSchemaUseNullkey(true)
350
+ expect(db.autoSchemaUseNullkey()).to eq true
351
+ db.setAutoSchemaUseNullkey(false)
352
+ expect(db.autoSchemaUseNullkey()).to eq false
353
+ expect(Transactd::Database::compatibleMode()).to eq Transactd::Database::CMP_MODE_MYSQL_NULL
354
+ Transactd::Database::setCompatibleMode(Transactd::Database::CMP_MODE_OLD_NULL)
355
+ expect(Transactd::Database::compatibleMode()).to eq Transactd::Database::CMP_MODE_OLD_NULL
356
+ Transactd::Database::setCompatibleMode(Transactd::Database::CMP_MODE_MYSQL_NULL)
357
+ expect(Transactd::Database::compatibleMode()).to eq Transactd::Database::CMP_MODE_MYSQL_NULL
358
+ db.close()
359
+ end
360
+
361
+ it 'check' do
362
+ Transactd::Database::setCompatibleMode(Transactd::Database::CMP_MODE_MYSQL_NULL)
363
+ db = Transactd::Database.new()
364
+ openDatabase(db)
365
+ openTableOnce(db)
366
+ dbdef = db.dbDef()
367
+ mysql_5_5 = isMySQL5_5(db)
368
+ td = dbdef.tableDefs(1)
369
+ # isMysqlNullMode
370
+ expect(td.isMysqlNullMode()).to eq true
371
+ # recordlen
372
+ len = 145
373
+ len += 4 if (mysql_5_5)
374
+ len -= 3 if (isLegacyTimeFormat(db))
375
+ expect(td.recordlen()).to eq len
376
+ # size
377
+ expect(td.size()).to eq 1184
378
+ # InUse
379
+ expect(td.inUse()).to eq 0
380
+ # nullfields
381
+ expect(td.nullfields()).to eq 2
382
+ # fieldNumByName
383
+ expect(td.fieldNumByName("tel")).to eq 3
384
+ # default value
385
+ fd = td.fieldDef(1)
386
+ expect(fd.defaultValue()).to eq "John"
387
+ fd = td.fieldDef(2)
388
+ expect(fd.defaultValue()).to eq "10"
389
+ fd = td.fieldDef(3)
390
+ expect(fd.isDefaultNull()).to eq true
391
+ fd = td.fieldDef(4)
392
+ expect(fd.defaultValue()).to eq Transactd::DFV_TIMESTAMP_DEFAULT.to_i().to_s()
393
+ expect(fd.isTimeStampOnUpdate()).to eq true
394
+ fd = td.fieldDef(5)
395
+ expect(fd.isTimeStampOnUpdate()).to eq false
396
+ # synchronizeSeverSchema
397
+ fd = td.fieldDef(1)
398
+ len = fd.len
399
+ fd.setLenByCharnum(19)
400
+ expect(len).not_to eq fd.len
401
+ dbdef.synchronizeSeverSchema(1)
402
+ td = dbdef.tableDefs(1)
403
+ fd = td.fieldDef(1)
404
+ expect(len).to eq fd.len
405
+ # syncronize default value
406
+ fd = td.fieldDef(1)
407
+ expect(fd.defaultValue()).to eq "John"
408
+ fd = td.fieldDef(2)
409
+ expect(fd.defaultValue()).to eq "10"
410
+ fd = td.fieldDef(3)
411
+ expect(fd.isDefaultNull()).to eq true
412
+ fd = td.fieldDef(4)
413
+ expect(fd.isTimeStampOnUpdate()).to eq true
414
+ fd = td.fieldDef(5)
415
+ expect(fd.isTimeStampOnUpdate()).to eq false
416
+
417
+ db.close()
418
+ end
419
+
420
+ it 'null' do
421
+ db = Transactd::Database.new()
422
+ openDatabase(db)
423
+ dbdef = db.dbDef()
424
+ td = dbdef.tableDefs(1)
425
+ # nullable
426
+ fd = td.fieldDef(3)
427
+ expect(fd.isNullable()).to eq true
428
+ # getSqlStringForCreateTable
429
+ sql = db.getSqlStringForCreateTable("extention")
430
+ expect(db.stat()).to eq 0
431
+ expect(sql).to eq 'CREATE TABLE `extention` (`id` INT NOT NULL ,`comment` VARCHAR(60) binary NULL DEFAULT NULL,`bits` BIGINT NOT NULL , UNIQUE key0(`id`)) ENGINE=InnoDB default charset=utf8'
432
+ # setValidationTarget(bool isMariadb, uchar_td srvMinorVersion)
433
+ td = dbdef.tableDefs(1)
434
+ td.setValidationTarget(true, 0)
435
+
436
+ q = Transactd::Query.new()
437
+ atu = Transactd::ActiveTable.new(db, "user")
438
+ # segmentsSizeForInValue
439
+ expect(q.segmentsForInValue(3).getJoinKeySize()).to eq 3
440
+ q.reset()
441
+ expect(q.getJoinKeySize()).to eq 0
442
+ # keyValue null
443
+ tb1 = atu.table()
444
+ tb1.setFV(2, nil)
445
+ expect(tb1.getFVNull(2)).to eq true
446
+ tb1.setFVNull(2, false)
447
+ expect(tb1.getFVNull(2)).to eq false
448
+ atu.index(1).keyValue(nil)
449
+ expect(tb1.getFVNull(2)).to eq true
450
+ # isNull setNull
451
+ atu.alias("名前", "name")
452
+ q.select("id", "name", "group", "tel").where("id", "<=", 10)
453
+ rs = atu.index(0).keyValue(1).read(q)
454
+ expect(rs.count()).to eq 10
455
+ rec = rs.first()
456
+ expect(rec[3].isNull()).to eq true
457
+ rec[3].setNull(false)
458
+ expect(rec[3].isNull()).to eq false
459
+ rec[3].setValue(nil)
460
+ expect(rec[3].isNull()).to eq true
461
+ # Join null
462
+ q.reset()
463
+ q.select("comment").optimize(Transactd::QueryBase::JoinHasOneOrHasMany)
464
+ ate = Transactd::ActiveTable.new(db, "extention")
465
+ ate.index(0).join(rs, q, "id")
466
+ last = rs.reverse().first()
467
+ expect(rs.count()).to eq 10
468
+ expect(last["id"].i()).to eq 10
469
+ expect(last["id"].i64()).to eq 10
470
+ expect(last["id"].d()).to eq 10
471
+ expect(rec[4].isNull()).to eq false
472
+ rec[4].setNull(true)
473
+ expect(rec[4].isNull()).to eq true
474
+ # setValue null
475
+ expect(rec[4].isNull()).to eq true
476
+ rec[4].setNull(false)
477
+ expect(rec[4].isNull()).to eq false
478
+ rec[4].setValue(nil)
479
+ expect(rec[4].isNull()).to eq true
480
+ # WritableRecord.clear()
481
+ wr = atu.getWritableRecord()
482
+ wr.clear()
483
+ wr["id"].setValue(5)
484
+ wr["tel"].setValue("0236-99-9999")
485
+ wr.update()
486
+ wr.clear()
487
+ wr["id"].setValue(5)
488
+ expect(wr.read()).to eq true
489
+ expect(wr["tel"].str()).to eq "0236-99-9999"
490
+ # whereIsNull
491
+ q.reset()
492
+ q.select("id", "tel").whereIsNull("tel").reject(0xFFFF)
493
+ rs = atu.index(0).keyValue(0).read(q)
494
+ expect(rs.count()).to eq 999
495
+ # whereIsNotNull
496
+ q.reset()
497
+ q.select("id", "tel").whereIsNotNull("tel").reject(0xFFFF)
498
+ rs = atu.index(0).keyValue(0).read(q)
499
+ expect(rs.count()).to eq 1
500
+ # AndIsNull
501
+ q.reset()
502
+ q.select("id", "tel").where("id", "<=", 10).andIsNull("tel").reject(0xFFFF)
503
+ rs = atu.index(0).keyValue(0).read(q)
504
+ expect(rs.count()).to eq 9
505
+ # AndIsNotNull
506
+ q.reset()
507
+ q.select("id", "tel").where("id", "<", 10).andIsNotNull("tel").reject(0xFFFF)
508
+ rs = atu.index(0).keyValue(0).read(q)
509
+ expect(rs.count()).to eq 1
510
+ # OrIsNull
511
+ q.reset()
512
+ q.select("id", "tel").where("id", "<=", 10).orIsNull("tel").reject(0xFFFF)
513
+ rs = atu.index(0).keyValue(0).read(q)
514
+ expect(rs.count()).to eq 1000
515
+ # OrIsNotNull
516
+ q.reset()
517
+ q.select("id", "tel").where("id", "<=", 10).orIsNotNull("tel").reject(0xFFFF)
518
+ rs = atu.index(0).keyValue(0).read(q)
519
+ expect(rs.count()).to eq 10
520
+ # test recordset query
521
+ q.reset()
522
+ q.select("id", "name", "group", "tel")
523
+ rs = atu.index(0).keyValue(0).read(q)
524
+ expect(rs.count()).to eq 1000
525
+ # recordset whenIsNull
526
+ rq = Transactd::RecordsetQuery.new()
527
+ rq.whenIsNull("tel")
528
+ rs2 = rs.clone()
529
+ rs2 = rs2.matchBy(rq)
530
+ expect(rs2.count()).to eq 999
531
+ # recordset whenIsNotNull
532
+ rq.reset()
533
+ rq.whenIsNotNull("tel")
534
+ rs2 = rs.clone()
535
+ rs2 = rs2.matchBy(rq)
536
+ expect(rs2.count()).to eq 1
537
+ #recordset andIsNull
538
+ rq.reset()
539
+ rq.when("id", "<=", 10).andIsNull("tel")
540
+ rs2 = rs.clone()
541
+ rs2 = rs2.matchBy(rq)
542
+ expect(rs2.count()).to eq 9
543
+ # recordset andIsNotNull
544
+ rq.reset()
545
+ rq.when("id", "<", 10).andIsNotNull("tel")
546
+ rs2 = rs.clone()
547
+ rs2 = rs2.matchBy(rq)
548
+ expect(rs2.count()).to eq 1
549
+ # recordset orIsNull
550
+ rq.reset()
551
+ rq.when("id", "<=", 10).orIsNull("tel")
552
+ rs2 = rs.clone()
553
+ rs2 = rs2.matchBy(rq)
554
+ expect(rs2.count()).to eq 1000
555
+ # recordset orIsNotNull
556
+ rq.reset()
557
+ rq.when("id", "<=", 10).orIsNotNull("tel")
558
+ rs2 = rs.clone()
559
+ rs2 = rs2.matchBy(rq)
560
+ expect(rs2.count()).to eq 10
561
+ # setBin bin
562
+ hex_str = ['FF01FF02']
563
+ bin = hex_str.pack('H*')
564
+ wr["tel"].setBin(bin)
565
+ ret = wr["tel"].bin()
566
+ expect(ret.unpack('H*')[0].upcase()).to eq hex_str[0]
567
+ atu.release()
568
+ ate.release()
569
+ db.close()
570
+ end
571
+
572
+ it 'default null' do
573
+ db = Transactd::Database.new()
574
+ openDatabase(db)
575
+ mysql_5_5 = isMySQL5_5(db)
576
+ dbdef = db.dbDef()
577
+ td = dbdef.tableDefs(1)
578
+ # table::default NULL
579
+ tb = db.openTable("user")
580
+ expect(db.stat()).to eq 0
581
+ tb.setKeyNum(0)
582
+ tb.clearBuffer()
583
+ expect(tb.getFVNull(3)).to eq true
584
+ tb.clearBuffer(Transactd::Table::ClearNull)
585
+ expect(tb.getFVNull(3)).to eq false
586
+ # table NULL
587
+ tb.setFV("id", 1)
588
+ tb.seek()
589
+ expect(tb.stat()).to eq 0
590
+ expect(tb.getFVNull(3)).to eq true
591
+ expect(tb.getFVNull("tel")).to eq true
592
+ tb.setFVNull(3, false)
593
+ expect(tb.getFVNull(3)).to eq false
594
+ # setFV null
595
+ tb.setFVNull("tel", true)
596
+ expect(tb.getFVNull("tel")).to eq true
597
+ tb.setFVNull("tel", false)
598
+ expect(tb.getFVNull("tel")).to eq false
599
+ tb.setFV("tel", nil)
600
+ expect(tb.getFVNull("tel")).to eq true
601
+ # timestamp format
602
+ date = Transactd::btrdtoa(Transactd::getNowDate(), true)
603
+ expect(tb.getFVstr("update_datetime")[0...10]).to eq date
604
+ if (! mysql_5_5)
605
+ expect(tb.getFVstr("create_datetime")[0...10]).to eq date
606
+ end
607
+ # setTimestampMode
608
+ tb.setTimestampMode(Transactd::TIMESTAMP_VALUE_CONTROL)
609
+ tb.setTimestampMode(Transactd::TIMESTAMP_ALWAYS)
610
+ # isMysqlNullMode
611
+ expect(tb.tableDef().isMysqlNullMode()).to eq true
612
+ expect(td.inUse()).to eq 1
613
+ tb.close()
614
+ tb.release()
615
+ expect(td.inUse()).to eq 0
616
+ db.close()
617
+ end
618
+
619
+ it 'bit' do
620
+ db = Transactd::Database.new()
621
+ openDatabase(db)
622
+ tb = db.openTable("extention")
623
+ expect(db.stat()).to eq 0
624
+ tb.setKeyNum(0)
625
+ tb.setFV('id', 1)
626
+ tb.seek()
627
+ expect(tb.stat()).to eq 0
628
+ bits = Transactd::Bitset.new()
629
+ bits[63] = true
630
+ bits[2] = true
631
+ bits[5] = true
632
+ tb.setFV('bits', bits)
633
+ tb.update()
634
+ expect(tb.stat()).to eq 0
635
+ q = Transactd::Query.new()
636
+ at = Transactd::ActiveTable.new(db, "extention")
637
+ q.where('id', '=', 1)
638
+ rs = at.index(0).keyValue(1).read(q)
639
+ expect(rs.size()).to eq 1
640
+ bits = rs[0]['bits'].getBits()
641
+ expect(bits.get(63)).to eq true
642
+ expect(bits.get(2)).to eq true
643
+ expect(bits.get(5)).to eq true
644
+ expect(bits.get(62)).to eq false
645
+ expect(bits.get(0)).to eq false
646
+ expect(bits.get(12)).to eq false
647
+ expect(bits[63]).to eq true
648
+ expect(bits[2]).to eq true
649
+ expect(bits[5]).to eq true
650
+ expect(bits[62]).to eq false
651
+ expect(bits[0]).to eq false
652
+ expect(bits[12]).to eq false
653
+ wr = at.getWritableRecord()
654
+ wr['id'] = 1
655
+ bits[63] = false
656
+ bits[12] = true
657
+ bits[0] = true
658
+ bits[62] = true
659
+ wr['bits'] = bits
660
+ wr.update()
661
+ tb.setFV('id', 1)
662
+ tb.seek()
663
+ expect(tb.stat()).to eq 0
664
+ bits = tb.getFVbits('bits')
665
+ expect(bits.get(63)).to eq false
666
+ expect(bits.get(2)).to eq true
667
+ expect(bits.get(5)).to eq true
668
+ expect(bits.get(12)).to eq true
669
+ expect(bits.get(0)).to eq true
670
+ expect(bits.get(62)).to eq true
671
+ expect(bits.get(11)).to eq false
672
+ expect(bits.get(13)).to eq false
673
+ expect(bits[63]).to eq false
674
+ expect(bits[2]).to eq true
675
+ expect(bits[5]).to eq true
676
+ expect(bits[12]).to eq true
677
+ expect(bits[0]).to eq true
678
+ expect(bits[62]).to eq true
679
+ expect(bits[11]).to eq false
680
+ expect(bits[13]).to eq false
681
+ end
682
+
683
+ it 'bitset' do
684
+ bits1 = Transactd::Bitset.new()
685
+ bits2 = Transactd::Bitset.new()
686
+ bits1[0] = true
687
+ bits1[1] = true
688
+ bits1[63] = true
689
+ bits2[0] = true
690
+ bits2[1] = false
691
+ bits2[63] = true
692
+ expect(bits1.equals(bits2)).to eq false
693
+ expect(bits1.contains(bits2)).to eq true
694
+ expect(bits2.contains(bits1)).to eq false
695
+ all = false
696
+ expect(bits2.contains(bits1, all)).to eq true
697
+ end
698
+
699
+ it 'set, enum, bit' do
700
+ db = Transactd::Database.new()
701
+ openDatabaseAutoSchema(db)
702
+ expect(db.stat()).to eq 0
703
+ createSetEnumBitTable(db)
704
+ ats = Transactd::ActiveTable.new(db, SEB_TABLENAME)
705
+ q = Transactd::Query.new()
706
+ q.reset().all()
707
+ rs = ats.index(0).keyValue(0).read(q)
708
+ expect(rs.size()).to eq 7
709
+ expect(rs[0]['id'].i64()).to eq 1
710
+ expect(rs[0]['set5'].i64()).to eq 1
711
+ expect(rs[0]['set64'].i64()).to eq 1
712
+ expect(rs[0]['enum2'].i64()).to eq 2
713
+ expect(rs[0]['enum260'].i64()).to eq 1
714
+ expect(rs[0]['bit1'].i64()).to eq 1
715
+ expect(rs[0]['bit8'].i64()).to eq 1
716
+ expect(rs[0]['bit32'].i64()).to eq 1
717
+ expect(rs[0]['bit64'].i64()).to eq 1
718
+ expect(rs[1]['id'].i64()).to eq 2
719
+ expect(rs[1]['set5'].i64()).to eq 31
720
+ expect(rs[1]['set64'].i64()).to eq -9223372036854775807
721
+ expect(rs[1]['enum2'].i64()).to eq 1
722
+ expect(rs[1]['enum260'].i64()).to eq 260
723
+ expect(rs[1]['bit1'].i64()).to eq 1
724
+ expect(rs[1]['bit8'].i64()).to eq 0xFF
725
+ expect(rs[1]['bit32'].i64()).to eq 0xFFFFFFFF
726
+ expect(rs[1]['bit64'].i64()).to eq -1
727
+ expect(rs[2]['id'].i64()).to eq 3
728
+ expect(rs[2]['set5'].i64()).to eq 0
729
+ expect(rs[2]['set64'].i64()).to eq 0
730
+ expect(rs[2]['enum2'].i64()).to eq 0
731
+ expect(rs[2]['enum260'].i64()).to eq 0
732
+ expect(rs[2]['bit1'].i64()).to eq 0
733
+ expect(rs[2]['bit8'].i64()).to eq 0
734
+ expect(rs[2]['bit32'].i64()).to eq 0
735
+ expect(rs[2]['bit64'].i64()).to eq 0
736
+ expect(rs[3]['id'].i64()).to eq 4
737
+ expect(rs[3]['set5'].isNull()).to eq true
738
+ expect(rs[3]['set64'].isNull()).to eq true
739
+ expect(rs[3]['enum2'].isNull()).to eq true
740
+ expect(rs[3]['enum260'].isNull()).to eq true
741
+ expect(rs[3]['bit1'].isNull()).to eq true
742
+ expect(rs[3]['bit8'].isNull()).to eq true
743
+ expect(rs[3]['bit32'].isNull()).to eq true
744
+ expect(rs[3]['bit64'].isNull()).to eq true
745
+ ats.release()
746
+ db.close()
747
+ end
748
+ end