activerecord-rdb-adapter 0.9.0 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/fb.c +62 -71
- data/lib/active_model/type/integer.rb +68 -0
- data/lib/active_record/connection_adapters/rdb/database_statements.rb +85 -1
- data/lib/active_record/connection_adapters/rdb/schema_statements.rb +7 -4
- data/lib/active_record/connection_adapters/rdb_adapter.rb +9 -0
- data/lib/active_record/rdb_base.rb +1 -0
- data/lib/active_record/tasks/rdb_database_tasks.rb +9 -13
- data/lib/arel/visitors/rdb_visitor.rb +43 -20
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9d0576dbcd5a9724c79ac6ff18739649b3c4b3c38b7b5e3ac9018804a0389b6
|
4
|
+
data.tar.gz: 1bfd97cbeb22b5d9beba889f5d3a05cf620563e6e27b2426e01b99b35afb55be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09e1856d986538037bf3e67c6e5b330a06a6454df046cf4579a05634e9c96a2b74401aeebf45f7ad721a78a684ca886db69289f97728871bd9598bc109f362bd'
|
7
|
+
data.tar.gz: 63f991b80b280a186f3bb01f911cc293970e8bc82a1b07b386164f9e5b6e0fe505c5cd711ac7c72ce5d8d18044e60d40beba4ed7c481636e144b9a8fd3889e0d
|
data/fb.c
CHANGED
@@ -152,9 +152,9 @@ static long calculate_buffsize(XSQLDA *sqlda)
|
|
152
152
|
alignment = sizeof(short);
|
153
153
|
}
|
154
154
|
|
155
|
-
offset = FB_ALIGN(
|
155
|
+
offset = FB_ALIGN(offset, alignment);
|
156
156
|
offset += length;
|
157
|
-
offset = FB_ALIGN(
|
157
|
+
offset = FB_ALIGN(offset, sizeof(short));
|
158
158
|
offset += sizeof(short);
|
159
159
|
}
|
160
160
|
|
@@ -166,11 +166,11 @@ static VALUE fb_error_msg(const ISC_STATUS *isc_status)
|
|
166
166
|
{
|
167
167
|
char msg[1024];
|
168
168
|
VALUE result = rb_str_new(NULL, 0);
|
169
|
-
|
169
|
+
|
170
170
|
while (fb_interpret(msg, 1024, &isc_status))
|
171
171
|
{
|
172
172
|
result = rb_str_cat(result, msg, strlen(msg));
|
173
|
-
result = rb_str_cat(result, "\n",
|
173
|
+
result = rb_str_cat(result, "\n", strlen("\n"));
|
174
174
|
}
|
175
175
|
return result;
|
176
176
|
}
|
@@ -234,7 +234,7 @@ static VALUE fb_mkdate(struct tm *tm)
|
|
234
234
|
{
|
235
235
|
return rb_funcall(
|
236
236
|
rb_cDate, rb_intern("civil"), 3,
|
237
|
-
INT2FIX(1900 + tm->tm_year), INT2FIX(tm->tm_mon + 1), INT2FIX(tm->tm_mday));
|
237
|
+
INT2FIX(1900 + tm->tm_year), INT2FIX(tm->tm_mon + 1), INT2FIX(tm->tm_mday));
|
238
238
|
}
|
239
239
|
|
240
240
|
static int responds_like_date(VALUE obj)
|
@@ -466,7 +466,7 @@ static XSQLDA* sqlda_alloc(long cols)
|
|
466
466
|
{
|
467
467
|
XSQLDA *sqlda;
|
468
468
|
|
469
|
-
sqlda = (XSQLDA*)xmalloc(XSQLDA_LENGTH(
|
469
|
+
sqlda = (XSQLDA*)xmalloc(XSQLDA_LENGTH(cols));
|
470
470
|
#ifdef SQLDA_CURRENT_VERSION
|
471
471
|
sqlda->version = SQLDA_CURRENT_VERSION;
|
472
472
|
#else
|
@@ -686,6 +686,8 @@ static char* trans_parseopts(VALUE opt, long *tpb_len)
|
|
686
686
|
s++;
|
687
687
|
}
|
688
688
|
|
689
|
+
used = 0;
|
690
|
+
size = 0;
|
689
691
|
tpb = NULL;
|
690
692
|
memset((void *)check_f, 0, sizeof(check_f));
|
691
693
|
|
@@ -739,11 +741,7 @@ static char* trans_parseopts(VALUE opt, long *tpb_len)
|
|
739
741
|
check_f[target_p->position] = 1;
|
740
742
|
} else {
|
741
743
|
if (used + 1 > size) {
|
742
|
-
|
743
|
-
if (tmp_tpb == NULL) {
|
744
|
-
} else {
|
745
|
-
tpb = tmp_tpb;
|
746
|
-
}
|
744
|
+
tpb = (char *)realloc(tpb, size + TPBBUFF_ALLOC);
|
747
745
|
size += TPBBUFF_ALLOC;
|
748
746
|
}
|
749
747
|
tpb[used] = target_p->optval;
|
@@ -779,7 +777,7 @@ static char* trans_parseopts(VALUE opt, long *tpb_len)
|
|
779
777
|
if (*resv_p == '\0' || (ofs = strspn(resv_p, LIST_DELIMIT)) < 0) {
|
780
778
|
resv_p++;
|
781
779
|
} else {
|
782
|
-
resv_p = &resv_p[
|
780
|
+
resv_p = &resv_p[ofs];
|
783
781
|
tblend_p = strpbrk(resv_p, LIST_DELIMIT);
|
784
782
|
if (tblend_p) {
|
785
783
|
tbl_len = tblend_p - resv_p;
|
@@ -793,7 +791,7 @@ static char* trans_parseopts(VALUE opt, long *tpb_len)
|
|
793
791
|
|
794
792
|
if (tbl_len > 0) {
|
795
793
|
if (used + tbl_len + 3 > size) {
|
796
|
-
tpb = (char*)xrealloc(tpb,
|
794
|
+
tpb = (char*)xrealloc(tpb, size+TPBBUFF_ALLOC);
|
797
795
|
size += TPBBUFF_ALLOC;
|
798
796
|
}
|
799
797
|
tpb[used+1] = (char)tbl_len;
|
@@ -1283,15 +1281,15 @@ static void fb_cursor_free(struct FbCursor *fb_cursor)
|
|
1283
1281
|
|
1284
1282
|
static VALUE sql_decimal_to_bigdecimal(long long sql_data, int scale)
|
1285
1283
|
{
|
1286
|
-
|
1284
|
+
unsigned long i;
|
1287
1285
|
char bigdecimal_buffer[23];
|
1288
|
-
|
1286
|
+
unsigned long bigdecimal_dot;
|
1289
1287
|
sprintf(bigdecimal_buffer, "%022lld", sql_data);
|
1290
|
-
bigdecimal_dot = strlen(bigdecimal_buffer) +
|
1288
|
+
bigdecimal_dot = strlen(bigdecimal_buffer) + scale;
|
1291
1289
|
for (i = strlen(bigdecimal_buffer); i > bigdecimal_dot; i--)
|
1292
1290
|
bigdecimal_buffer[i] = bigdecimal_buffer[i-1];
|
1293
1291
|
bigdecimal_buffer[bigdecimal_dot] = '.';
|
1294
|
-
return rb_funcall(
|
1292
|
+
return rb_funcall(rb_cObject, rb_intern("BigDecimal"), 1, rb_str_new2(bigdecimal_buffer));
|
1295
1293
|
}
|
1296
1294
|
|
1297
1295
|
static VALUE object_to_unscaled_bigdecimal(VALUE object, int scale)
|
@@ -1302,7 +1300,7 @@ static VALUE object_to_unscaled_bigdecimal(VALUE object, int scale)
|
|
1302
1300
|
ratio *= 10;
|
1303
1301
|
if (TYPE(object) == T_FLOAT)
|
1304
1302
|
object = rb_funcall(object, rb_intern("to_s"), 0);
|
1305
|
-
object = rb_funcall(
|
1303
|
+
object = rb_funcall(rb_cObject, rb_intern("BigDecimal"), 1, object);
|
1306
1304
|
object = rb_funcall(object, rb_intern("*"), 1, LONG2NUM(ratio));
|
1307
1305
|
return rb_funcall(object, rb_intern("round"), 0);
|
1308
1306
|
}
|
@@ -1354,36 +1352,36 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1354
1352
|
switch (dtp) {
|
1355
1353
|
case SQL_TEXT :
|
1356
1354
|
alignment = 1;
|
1357
|
-
offset = FB_ALIGN(
|
1358
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1355
|
+
offset = FB_ALIGN(offset, alignment);
|
1356
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1359
1357
|
obj = rb_obj_as_string(obj);
|
1360
1358
|
if (RSTRING_LEN(obj) > var->sqllen) {
|
1361
1359
|
rb_raise(rb_eRangeError, "CHAR overflow: %ld bytes exceeds %d byte(s) allowed.",
|
1362
1360
|
RSTRING_LEN(obj), var->sqllen);
|
1363
1361
|
}
|
1364
|
-
memcpy(var->sqldata, RSTRING_PTR(obj),
|
1362
|
+
memcpy(var->sqldata, RSTRING_PTR(obj), RSTRING_LEN(obj));
|
1365
1363
|
var->sqllen = RSTRING_LEN(obj);
|
1366
1364
|
offset += var->sqllen + 1;
|
1367
1365
|
break;
|
1368
1366
|
|
1369
1367
|
case SQL_VARYING :
|
1370
1368
|
alignment = sizeof(short);
|
1371
|
-
offset = FB_ALIGN(
|
1372
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1369
|
+
offset = FB_ALIGN(offset, alignment);
|
1370
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1373
1371
|
vary = (VARY *)var->sqldata;
|
1374
1372
|
obj = rb_obj_as_string(obj);
|
1375
1373
|
if (RSTRING_LEN(obj) > var->sqllen) {
|
1376
1374
|
rb_raise(rb_eRangeError, "VARCHAR overflow: %ld bytes exceeds %d byte(s) allowed.",
|
1377
1375
|
RSTRING_LEN(obj), var->sqllen);
|
1378
1376
|
}
|
1379
|
-
memcpy(vary->vary_string, RSTRING_PTR(obj),
|
1377
|
+
memcpy(vary->vary_string, RSTRING_PTR(obj), RSTRING_LEN(obj));
|
1380
1378
|
vary->vary_length = RSTRING_LEN(obj);
|
1381
1379
|
offset += vary->vary_length + sizeof(short);
|
1382
1380
|
break;
|
1383
1381
|
|
1384
1382
|
case SQL_SHORT :
|
1385
|
-
offset = FB_ALIGN(
|
1386
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1383
|
+
offset = FB_ALIGN(offset, alignment);
|
1384
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1387
1385
|
if (var->sqlscale < 0) {
|
1388
1386
|
lvalue = NUM2LONG(object_to_unscaled_bigdecimal(obj, var->sqlscale));
|
1389
1387
|
} else {
|
@@ -1397,8 +1395,8 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1397
1395
|
break;
|
1398
1396
|
|
1399
1397
|
case SQL_LONG :
|
1400
|
-
offset = FB_ALIGN(
|
1401
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1398
|
+
offset = FB_ALIGN(offset, alignment);
|
1399
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1402
1400
|
if (var->sqlscale < 0) {
|
1403
1401
|
lvalue = NUM2LONG(object_to_unscaled_bigdecimal(obj, var->sqlscale));
|
1404
1402
|
} else {
|
@@ -1412,8 +1410,8 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1412
1410
|
break;
|
1413
1411
|
|
1414
1412
|
case SQL_FLOAT :
|
1415
|
-
offset = FB_ALIGN(
|
1416
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1413
|
+
offset = FB_ALIGN(offset, alignment);
|
1414
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1417
1415
|
obj = double_from_obj(obj);
|
1418
1416
|
dvalue = NUM2DBL(obj);
|
1419
1417
|
if (dvalue >= 0.0) {
|
@@ -1429,8 +1427,8 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1429
1427
|
break;
|
1430
1428
|
|
1431
1429
|
case SQL_DOUBLE :
|
1432
|
-
offset = FB_ALIGN(
|
1433
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1430
|
+
offset = FB_ALIGN(offset, alignment);
|
1431
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1434
1432
|
obj = double_from_obj(obj);
|
1435
1433
|
dvalue = NUM2DBL(obj);
|
1436
1434
|
*(double *)var->sqldata = dvalue;
|
@@ -1438,8 +1436,8 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1438
1436
|
break;
|
1439
1437
|
|
1440
1438
|
case SQL_INT64 :
|
1441
|
-
offset = FB_ALIGN(
|
1442
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1439
|
+
offset = FB_ALIGN(offset, alignment);
|
1440
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1443
1441
|
|
1444
1442
|
if (var->sqlscale < 0) {
|
1445
1443
|
llvalue = NUM2LL(object_to_unscaled_bigdecimal(obj, var->sqlscale));
|
@@ -1452,8 +1450,8 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1452
1450
|
break;
|
1453
1451
|
|
1454
1452
|
case SQL_BLOB :
|
1455
|
-
offset = FB_ALIGN(
|
1456
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1453
|
+
offset = FB_ALIGN(offset, alignment);
|
1454
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1457
1455
|
obj = rb_obj_as_string(obj);
|
1458
1456
|
|
1459
1457
|
blob_handle = 0;
|
@@ -1481,24 +1479,24 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1481
1479
|
break;
|
1482
1480
|
|
1483
1481
|
case SQL_TIMESTAMP :
|
1484
|
-
offset = FB_ALIGN(
|
1485
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1482
|
+
offset = FB_ALIGN(offset, alignment);
|
1483
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1486
1484
|
tm_from_timestamp(&tms, obj);
|
1487
1485
|
isc_encode_timestamp(&tms, (ISC_TIMESTAMP *)var->sqldata);
|
1488
1486
|
offset += alignment;
|
1489
1487
|
break;
|
1490
1488
|
|
1491
1489
|
case SQL_TYPE_TIME :
|
1492
|
-
offset = FB_ALIGN(
|
1493
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1490
|
+
offset = FB_ALIGN(offset, alignment);
|
1491
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1494
1492
|
tm_from_timestamp(&tms, obj);
|
1495
1493
|
isc_encode_sql_time(&tms, (ISC_TIME *)var->sqldata);
|
1496
1494
|
offset += alignment;
|
1497
1495
|
break;
|
1498
1496
|
|
1499
1497
|
case SQL_TYPE_DATE :
|
1500
|
-
offset = FB_ALIGN(
|
1501
|
-
var->sqldata = (char *)(fb_cursor->i_buffer +
|
1498
|
+
offset = FB_ALIGN(offset, alignment);
|
1499
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1502
1500
|
tm_from_date(&tms, obj);
|
1503
1501
|
isc_encode_sql_date(&tms, (ISC_DATE *)var->sqldata);
|
1504
1502
|
offset += alignment;
|
@@ -1519,29 +1517,27 @@ static void fb_cursor_set_inputparams(struct FbCursor *fb_cursor, long argc, VAL
|
|
1519
1517
|
#endif
|
1520
1518
|
|
1521
1519
|
#if (FB_API_VER >= 30)
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
offset = FB_ALIGN((size_t)offset, alignment);
|
1526
|
-
var->sqldata = (char *)(fb_cursor->i_buffer + (size_t)offset);
|
1520
|
+
case SQL_BOOLEAN:
|
1521
|
+
offset = FB_ALIGN(offset, alignment);
|
1522
|
+
var->sqldata = (char *)(fb_cursor->i_buffer + offset);
|
1527
1523
|
*(bool *)var->sqldata = obj;
|
1528
|
-
offset += alignment;
|
1529
|
-
|
1524
|
+
offset += alignment;
|
1525
|
+
break;
|
1530
1526
|
#endif
|
1531
1527
|
default :
|
1532
1528
|
rb_raise(rb_eFbError, "Specified table includes unsupported datatype (%d)", dtp);
|
1533
1529
|
}
|
1534
1530
|
|
1535
1531
|
if (var->sqltype & 1) {
|
1536
|
-
offset = FB_ALIGN(
|
1537
|
-
var->sqlind = (short *)(fb_cursor->i_buffer +
|
1532
|
+
offset = FB_ALIGN(offset, sizeof(short));
|
1533
|
+
var->sqlind = (short *)(fb_cursor->i_buffer + offset);
|
1538
1534
|
*var->sqlind = 0;
|
1539
1535
|
offset += sizeof(short);
|
1540
1536
|
}
|
1541
1537
|
} else if (var->sqltype & 1) {
|
1542
1538
|
var->sqldata = 0;
|
1543
|
-
offset = FB_ALIGN(
|
1544
|
-
var->sqlind = (short *)(fb_cursor->i_buffer +
|
1539
|
+
offset = FB_ALIGN(offset, sizeof(short));
|
1540
|
+
var->sqlind = (short *)(fb_cursor->i_buffer + offset);
|
1545
1541
|
*var->sqlind = -1;
|
1546
1542
|
offset += sizeof(short);
|
1547
1543
|
} else {
|
@@ -1620,10 +1616,7 @@ static VALUE precision_from_sqlvar(XSQLVAR *sqlvar)
|
|
1620
1616
|
case SQL_BLOB: return Qnil;
|
1621
1617
|
case SQL_ARRAY: return Qnil;
|
1622
1618
|
#if (FB_API_VER >= 30)
|
1623
|
-
|
1624
|
-
case blr_bool:
|
1625
|
-
case blr_boolean:
|
1626
|
-
return Qnil;
|
1619
|
+
case SQL_BOOLEAN: return Qnil;
|
1627
1620
|
#endif
|
1628
1621
|
case SQL_QUAD: return Qnil;
|
1629
1622
|
case SQL_TYPE_TIME: return Qnil;
|
@@ -1746,11 +1739,11 @@ static void fb_cursor_fetch_prep(struct FbCursor *fb_cursor)
|
|
1746
1739
|
length += sizeof(short);
|
1747
1740
|
alignment = sizeof(short);
|
1748
1741
|
}
|
1749
|
-
offset = FB_ALIGN(
|
1750
|
-
var->sqldata = (char*)(fb_cursor->o_buffer +
|
1742
|
+
offset = FB_ALIGN(offset, alignment);
|
1743
|
+
var->sqldata = (char*)(fb_cursor->o_buffer + offset);
|
1751
1744
|
offset += length;
|
1752
|
-
offset = FB_ALIGN(
|
1753
|
-
var->sqlind = (short*)(fb_cursor->o_buffer +
|
1745
|
+
offset = FB_ALIGN(offset, sizeof(short));
|
1746
|
+
var->sqlind = (short*)(fb_cursor->o_buffer + offset);
|
1754
1747
|
offset += sizeof(short);
|
1755
1748
|
}
|
1756
1749
|
}
|
@@ -1922,11 +1915,9 @@ static VALUE fb_cursor_fetch(struct FbCursor *fb_cursor)
|
|
1922
1915
|
break;
|
1923
1916
|
|
1924
1917
|
#if (FB_API_VER >= 30)
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
val = ((*(bool*)var->sqldata) == true) ? Qtrue : Qfalse;
|
1929
|
-
break;
|
1918
|
+
case SQL_BOOLEAN:
|
1919
|
+
val = (*(bool*)var->sqldata) ? Qtrue : Qfalse;
|
1920
|
+
break;
|
1930
1921
|
#endif
|
1931
1922
|
|
1932
1923
|
default:
|
@@ -2045,7 +2036,7 @@ static VALUE cursor_execute2(VALUE args)
|
|
2045
2036
|
if (in_params) {
|
2046
2037
|
length = calculate_buffsize(fb_cursor->i_sqlda);
|
2047
2038
|
if (length > fb_cursor->i_buffer_size) {
|
2048
|
-
fb_cursor->i_buffer = xrealloc(fb_cursor->i_buffer,
|
2039
|
+
fb_cursor->i_buffer = xrealloc(fb_cursor->i_buffer, length);
|
2049
2040
|
fb_cursor->i_buffer_size = length;
|
2050
2041
|
}
|
2051
2042
|
}
|
@@ -2090,7 +2081,7 @@ static VALUE cursor_execute2(VALUE args)
|
|
2090
2081
|
/* Get the size of results buffer and reallocate it */
|
2091
2082
|
length = calculate_buffsize(fb_cursor->o_sqlda);
|
2092
2083
|
if (length > fb_cursor->o_buffer_size) {
|
2093
|
-
fb_cursor->o_buffer = xrealloc(fb_cursor->o_buffer,
|
2084
|
+
fb_cursor->o_buffer = xrealloc(fb_cursor->o_buffer, length);
|
2094
2085
|
fb_cursor->o_buffer_size = length;
|
2095
2086
|
}
|
2096
2087
|
|
@@ -2429,10 +2420,10 @@ static char* dbp_add_string(char *dbp, char isc_dbp_code, char *s, long *length)
|
|
2429
2420
|
long s_len = strlen(s);
|
2430
2421
|
*length += 2 + s_len;
|
2431
2422
|
REALLOC_N(dbp, char, *length);
|
2432
|
-
buf = dbp +
|
2423
|
+
buf = dbp + old_length;
|
2433
2424
|
*buf++ = isc_dbp_code;
|
2434
2425
|
*buf++ = (char)s_len;
|
2435
|
-
|
2426
|
+
memcpy(buf, s, s_len);
|
2436
2427
|
return dbp;
|
2437
2428
|
}
|
2438
2429
|
|
@@ -2650,7 +2641,7 @@ static VALUE connection_columns(VALUE self, VALUE table_name)
|
|
2650
2641
|
if (fb_connection->downcase_names && no_lowercase(name)) {
|
2651
2642
|
rb_funcall(name, id_downcase_bang, 0);
|
2652
2643
|
}
|
2653
|
-
if (rb_funcall(re_rdb,
|
2644
|
+
if (rb_funcall(re_rdb, rb_intern("match"), 1, domain) != Qnil) {
|
2654
2645
|
domain = Qnil;
|
2655
2646
|
}
|
2656
2647
|
if (sql_subtype == Qnil) {
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
module Type
|
5
|
+
class Integer < Value # :nodoc:
|
6
|
+
include Helpers::Numeric
|
7
|
+
|
8
|
+
DEFAULT_LIMIT = 8
|
9
|
+
|
10
|
+
def initialize(*)
|
11
|
+
super
|
12
|
+
@range = min_value...max_value
|
13
|
+
end
|
14
|
+
|
15
|
+
def type
|
16
|
+
:integer
|
17
|
+
end
|
18
|
+
|
19
|
+
def deserialize(value)
|
20
|
+
return if value.nil?
|
21
|
+
value.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def serialize(value)
|
25
|
+
result = cast(value)
|
26
|
+
if result
|
27
|
+
ensure_in_range(result)
|
28
|
+
end
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
33
|
+
# Workaround for Ruby 2.2 "private attribute?" warning.
|
34
|
+
protected
|
35
|
+
|
36
|
+
attr_reader :range
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def cast_value(value)
|
41
|
+
case value
|
42
|
+
when true then 1
|
43
|
+
when false then 0
|
44
|
+
else
|
45
|
+
value.to_i rescue nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def ensure_in_range(value)
|
50
|
+
unless range.cover?(value)
|
51
|
+
raise ActiveModel::RangeError, "#{value} is out of range for #{self.class} with limit #{_limit} bytes"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def max_value
|
56
|
+
1 << (_limit * 8 - 1) # 8 bits per byte with one bit for sign
|
57
|
+
end
|
58
|
+
|
59
|
+
def min_value
|
60
|
+
-max_value
|
61
|
+
end
|
62
|
+
|
63
|
+
def _limit
|
64
|
+
limit || DEFAULT_LIMIT
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -33,7 +33,7 @@ module ActiveRecord
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
rescue StandardError => e
|
36
|
-
raise e
|
36
|
+
raise e
|
37
37
|
end
|
38
38
|
|
39
39
|
def explain(arel, binds = [])
|
@@ -93,6 +93,90 @@ module ActiveRecord
|
|
93
93
|
def last_inserted_id(_result)
|
94
94
|
nil
|
95
95
|
end
|
96
|
+
|
97
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
98
|
+
fixture_inserts = fixture_set.map do |table_name, fixtures|
|
99
|
+
next if fixtures.empty?
|
100
|
+
|
101
|
+
build_fixture_sql(fixtures, table_name).collect {|f| f }
|
102
|
+
end.compact
|
103
|
+
|
104
|
+
table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name table}".dup }
|
105
|
+
sql = fixture_inserts.flatten(1)
|
106
|
+
sql.unshift(*table_deletes)
|
107
|
+
|
108
|
+
transaction(requires_new: true) do
|
109
|
+
sql.each do |s|
|
110
|
+
execute s, 'Fixture load'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def default_insert_value(column)
|
118
|
+
if column.default.nil?
|
119
|
+
Arel.sql('NULL')
|
120
|
+
else
|
121
|
+
Arel.sql(quote(column.default))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def build_fixture_sql(fixtures, table_name)
|
126
|
+
columns = schema_cache.columns_hash(table_name)
|
127
|
+
|
128
|
+
values = fixtures.map do |fixture|
|
129
|
+
fixture = fixture.stringify_keys
|
130
|
+
|
131
|
+
unknown_columns = fixture.keys - columns.keys
|
132
|
+
if unknown_columns.any?
|
133
|
+
raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
|
134
|
+
end
|
135
|
+
|
136
|
+
columns.map do |name, column|
|
137
|
+
if fixture.key?(name)
|
138
|
+
type = lookup_cast_type_from_column(column)
|
139
|
+
bind = Relation::QueryAttribute.new(name, fixture[name], type)
|
140
|
+
with_yaml_fallback(bind.value_for_database)
|
141
|
+
else
|
142
|
+
default_insert_value(column)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
sql ||= []
|
148
|
+
|
149
|
+
values.each_with_index do |row, i|
|
150
|
+
s = ''
|
151
|
+
s << "INSERT INTO #{quote_table_name(table_name)}"
|
152
|
+
|
153
|
+
unless columns.empty?
|
154
|
+
s << ' ('
|
155
|
+
columns.each_with_index do |x, y|
|
156
|
+
s << ', ' unless y == 0
|
157
|
+
s << quote_column_name(x[1].name)
|
158
|
+
end
|
159
|
+
s << ')'
|
160
|
+
end
|
161
|
+
|
162
|
+
s << ' VALUES ('
|
163
|
+
row.each_with_index do |value, k|
|
164
|
+
s << ', ' unless k == 0
|
165
|
+
case value
|
166
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
167
|
+
s << value.to_s
|
168
|
+
when Time
|
169
|
+
s << quote(value.strftime("%F %T"))
|
170
|
+
else
|
171
|
+
s << quote(value).to_s
|
172
|
+
end
|
173
|
+
end
|
174
|
+
s << ');'
|
175
|
+
sql << s
|
176
|
+
end
|
177
|
+
|
178
|
+
sql
|
179
|
+
end
|
96
180
|
end
|
97
181
|
end
|
98
182
|
end
|
@@ -59,6 +59,7 @@ module ActiveRecord
|
|
59
59
|
end
|
60
60
|
|
61
61
|
return if options[:sequence] == false || !needs_sequence
|
62
|
+
|
62
63
|
create_sequence(options[:sequence] || default_sequence_name(name))
|
63
64
|
trg_sql = <<-END_SQL
|
64
65
|
CREATE TRIGGER N$#{name.upcase} FOR #{name.upcase}
|
@@ -135,12 +136,13 @@ module ActiveRecord
|
|
135
136
|
create_sequence(options[:sequence] || default_sequence_name(table_name)) if type == :primary_key && options[:sequence] != false
|
136
137
|
|
137
138
|
return unless options[:position]
|
139
|
+
|
138
140
|
# position is 1-based but add 1 to skip id column
|
139
|
-
execute(squish_sql(<<-
|
141
|
+
execute(squish_sql(<<-END_SQL))
|
140
142
|
ALTER TABLE #{quote_table_name(table_name)}
|
141
143
|
ALTER COLUMN #{quote_column_name(column_name)}
|
142
144
|
POSITION #{options[:position] + 1}
|
143
|
-
|
145
|
+
END_SQL
|
144
146
|
end
|
145
147
|
|
146
148
|
def remove_column(table_name, column_name, type = nil, options = {})
|
@@ -349,6 +351,7 @@ module ActiveRecord
|
|
349
351
|
|
350
352
|
def integer_to_sql(limit)
|
351
353
|
return 'integer' if limit.nil?
|
354
|
+
|
352
355
|
case limit
|
353
356
|
when 1..2 then
|
354
357
|
'smallint'
|
@@ -375,10 +378,10 @@ module ActiveRecord
|
|
375
378
|
end
|
376
379
|
|
377
380
|
def string_to_sql(limit)
|
378
|
-
if limit && limit > 0
|
381
|
+
if limit && limit > 0 && limit < 255
|
379
382
|
"VARCHAR(#{limit})"
|
380
383
|
else
|
381
|
-
'VARCHAR(
|
384
|
+
'VARCHAR(255)'
|
382
385
|
end
|
383
386
|
end
|
384
387
|
|
@@ -86,6 +86,10 @@ module ActiveRecord
|
|
86
86
|
1499
|
87
87
|
end
|
88
88
|
|
89
|
+
def supports_multi_insert?
|
90
|
+
false
|
91
|
+
end
|
92
|
+
|
89
93
|
def active?
|
90
94
|
return false unless @connection.open?
|
91
95
|
# return true if @connection.transaction_started
|
@@ -145,6 +149,11 @@ module ActiveRecord
|
|
145
149
|
ActiveRecord::RecordNotUnique.new(message)
|
146
150
|
when /This operation is not defined for system tables/
|
147
151
|
ActiveRecord::ActiveRecordError.new(message)
|
152
|
+
when /Column does not belong to referenced table/,
|
153
|
+
/Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements/,
|
154
|
+
/The cursor identified in the UPDATE or DELETE statement is not positioned on a row/,
|
155
|
+
/Overflow occurred during data type conversion/
|
156
|
+
ActiveRecord::StatementInvalid.new(message)
|
148
157
|
else
|
149
158
|
super
|
150
159
|
end
|
@@ -1,24 +1,23 @@
|
|
1
|
-
require 'active_record/tasks/database_tasks'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
|
-
module Tasks
|
2
|
+
module Tasks # :nodoc:
|
5
3
|
class RdbDatabaseTasks # :nodoc:
|
6
|
-
delegate :rdb_connection_config, :establish_connection, to: ::ActiveRecord::Base
|
4
|
+
delegate :rdb_connection, :rdb_connection_config, :establish_connection, to: ::ActiveRecord::Base
|
7
5
|
|
8
|
-
def initialize(configuration
|
9
|
-
@root = root
|
6
|
+
def initialize(configuration)
|
10
7
|
@configuration = rdb_connection_config(configuration)
|
11
8
|
end
|
12
9
|
|
13
10
|
def create
|
14
11
|
rdb_database.create
|
12
|
+
# create_db
|
15
13
|
establish_connection configuration
|
16
14
|
rescue ::Fb::Error => e
|
17
|
-
raise unless e.message.include?('
|
15
|
+
raise unless e.message.include?('File exists')
|
18
16
|
raise DatabaseAlreadyExists
|
19
17
|
end
|
20
18
|
|
21
19
|
def drop
|
20
|
+
establish_connection configuration
|
22
21
|
rdb_database.drop
|
23
22
|
rescue ::Fb::Error => e
|
24
23
|
raise ::ActiveRecord::ConnectionNotEstablished, e.message
|
@@ -33,11 +32,11 @@ module ActiveRecord
|
|
33
32
|
create
|
34
33
|
end
|
35
34
|
|
36
|
-
def structure_dump(filename)
|
35
|
+
def structure_dump(filename, structure_dump_flags = nil)
|
37
36
|
isql :extract, output: filename
|
38
37
|
end
|
39
38
|
|
40
|
-
def structure_load(filename)
|
39
|
+
def structure_load(filename, structure_load_flags = nil)
|
41
40
|
isql input: filename
|
42
41
|
end
|
43
42
|
|
@@ -69,14 +68,11 @@ module ActiveRecord
|
|
69
68
|
# Finds the isql command line utility from the PATH
|
70
69
|
# Many linux distros call this program isql-fb, instead of isql
|
71
70
|
def isql_executable
|
72
|
-
|
73
|
-
exe = %w[isql-fb isql].detect(&method(:find_executable0))
|
74
|
-
exe || abort('Unable to find isql or isql-fb in your $PATH')
|
71
|
+
"/opt/RedDatabase/bin/isql"
|
75
72
|
end
|
76
73
|
|
77
74
|
attr_reader :configuration
|
78
75
|
|
79
|
-
attr_reader :root
|
80
76
|
end
|
81
77
|
end
|
82
78
|
end
|
@@ -3,21 +3,43 @@ module Arel
|
|
3
3
|
class Rdb < Arel::Visitors::ToSql # :nodoc
|
4
4
|
private
|
5
5
|
|
6
|
-
def
|
7
|
-
collector << "
|
6
|
+
def visit_Arel_Nodes_InsertStatement(o, collector)
|
7
|
+
collector << "INSERT INTO "
|
8
|
+
collector = visit o.relation, collector
|
9
|
+
|
10
|
+
unless o.columns.empty?
|
11
|
+
collector << " ("
|
12
|
+
o.columns.each_with_index do |x, i|
|
13
|
+
collector << ", " unless i == 0
|
14
|
+
collector << quote_column_name(x.name)
|
15
|
+
end
|
16
|
+
collector << ")"
|
17
|
+
end
|
18
|
+
|
19
|
+
if o.values
|
20
|
+
maybe_visit o.values, collector
|
21
|
+
elsif o.select
|
22
|
+
maybe_visit o.select, collector
|
23
|
+
else
|
24
|
+
collector
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def visit_Arel_Nodes_SelectStatement(o, collector)
|
29
|
+
collector << 'SELECT '
|
8
30
|
collector = visit o.offset, collector if o.offset && !o.limit
|
9
31
|
|
10
|
-
collector = o.cores.inject(collector)
|
32
|
+
collector = o.cores.inject(collector) do |c, x|
|
11
33
|
visit_Arel_Nodes_SelectCore(x, c)
|
12
|
-
|
34
|
+
end
|
13
35
|
|
14
36
|
unless o.orders.empty?
|
15
37
|
collector << ORDER_BY
|
16
38
|
len = o.orders.length - 1
|
17
|
-
o.orders.each_with_index
|
39
|
+
o.orders.each_with_index do |x, i|
|
18
40
|
collector = visit(x, collector)
|
19
41
|
collector << COMMA unless len == i
|
20
|
-
|
42
|
+
end
|
21
43
|
end
|
22
44
|
|
23
45
|
if o.limit && o.offset
|
@@ -29,7 +51,7 @@ module Arel
|
|
29
51
|
maybe_visit o.lock, collector
|
30
52
|
end
|
31
53
|
|
32
|
-
def visit_Arel_Nodes_SelectCore
|
54
|
+
def visit_Arel_Nodes_SelectCore(o, collector)
|
33
55
|
if o.set_quantifier
|
34
56
|
collector = visit o.set_quantifier, collector
|
35
57
|
collector << SPACE
|
@@ -44,7 +66,7 @@ module Arel
|
|
44
66
|
end
|
45
67
|
|
46
68
|
if o.source && !o.source.empty?
|
47
|
-
collector <<
|
69
|
+
collector << ' FROM '
|
48
70
|
collector = visit o.source, collector
|
49
71
|
end
|
50
72
|
|
@@ -69,7 +91,7 @@ module Arel
|
|
69
91
|
collector = maybe_visit o.having, collector
|
70
92
|
else
|
71
93
|
unless o.havings.empty?
|
72
|
-
collector <<
|
94
|
+
collector << ' HAVING '
|
73
95
|
inject_join o.havings, collector, AND
|
74
96
|
end
|
75
97
|
end
|
@@ -77,33 +99,34 @@ module Arel
|
|
77
99
|
collector
|
78
100
|
end
|
79
101
|
|
80
|
-
def visit_Arel_Nodes_Limit
|
81
|
-
collector <<
|
102
|
+
def visit_Arel_Nodes_Limit(o, collector)
|
103
|
+
collector << ' ROWS '
|
82
104
|
visit o.expr, collector
|
83
105
|
end
|
84
106
|
|
85
|
-
def visit_Arel_Nodes_Offset
|
86
|
-
collector <<
|
107
|
+
def visit_Arel_Nodes_Offset(o, collector)
|
108
|
+
collector << ' SKIP '
|
87
109
|
visit o.expr, collector
|
88
110
|
end
|
89
111
|
|
90
112
|
def limit_with_rows o, collector
|
91
|
-
o.offset.expr.value = ActiveModel::Attribute.with_cast_value(
|
113
|
+
o.offset.expr.value = ActiveModel::Attribute.with_cast_value('OFFSET'.freeze,
|
92
114
|
o.offset.expr.value.value + 1,
|
93
115
|
ActiveModel::Type.default_value)
|
94
116
|
offset = o.offset.expr.value
|
95
|
-
o.limit.expr.value = ActiveModel::Attribute.with_cast_value(
|
96
|
-
|
117
|
+
o.limit.expr.value = ActiveModel::Attribute.with_cast_value('LIMIT'.freeze,
|
118
|
+
o.limit.expr.value.value + (offset.value - 1),
|
97
119
|
ActiveModel::Type.default_value)
|
98
120
|
limit = o.limit.expr.value
|
99
|
-
collector <<
|
100
|
-
collector.add_bind(offset) {|i|
|
101
|
-
collector <<
|
102
|
-
collector.add_bind(limit) {|i|
|
121
|
+
collector << ' ROWS '
|
122
|
+
collector.add_bind(offset) { |i| '?' }
|
123
|
+
collector << ' TO '
|
124
|
+
collector.add_bind(limit) { |i| '?' }
|
103
125
|
end
|
104
126
|
|
105
127
|
def quote_column_name name
|
106
128
|
return name if Arel::Nodes::SqlLiteral === name
|
129
|
+
|
107
130
|
@connection.quote_column_name(name)
|
108
131
|
end
|
109
132
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-rdb-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Lobanov (RedSoft)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.2'
|
27
27
|
description: ActiveRecord RedDatabase 3+ and Firebird 3+ Adapter for Rails 5+
|
28
28
|
email: andrey.lobanov@red-soft.ru
|
29
29
|
executables: []
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- extconf.rb
|
36
36
|
- fb.c
|
37
37
|
- fb_extensions.rb
|
38
|
+
- lib/active_model/type/integer.rb
|
38
39
|
- lib/active_record/connection_adapters/rdb/database_limits.rb
|
39
40
|
- lib/active_record/connection_adapters/rdb/database_statements.rb
|
40
41
|
- lib/active_record/connection_adapters/rdb/quoting.rb
|
@@ -69,7 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
70
|
version: '0'
|
70
71
|
requirements:
|
71
72
|
- Firebird library fb
|
72
|
-
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.7.6.2
|
73
75
|
signing_key:
|
74
76
|
specification_version: 4
|
75
77
|
summary: ActiveRecord RedDatabase 3+ and Firebird 3+ Adapter
|