rubyfb 0.6.2 → 0.6.3
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/CHANGELOG +7 -0
- data/Rakefile +1 -1
- data/ext/Blob.c +2 -3
- data/ext/Row.c +38 -21
- data/ext/Row.h +0 -1
- data/ext/Statement.c +44 -0
- data/lib/active_record/connection_adapters/rubyfb_adapter.rb +16 -3
- data/lib/rubyfb_lib.so +0 -0
- data/lib/src.rb +10 -0
- data/rubyfb.gemspec +3 -3
- data/test/StatementTest.rb +10 -0
- metadata +21 -39
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
v0.6.3 ==
|
2
|
+
Fix change_column() migration method
|
3
|
+
Fix Segmentation fault in Row class (GC integration issues)
|
4
|
+
Remove deprecated require in rubyfb_adapter.rb
|
5
|
+
Fix Rails 3.2 "undefined method `accept' for nil:NilClass" - https://github.com/rails/rails/issues/4632
|
6
|
+
Add Rails 3.2 explain() support
|
7
|
+
|
1
8
|
v0.6.2 ==
|
2
9
|
Update arel visitors
|
3
10
|
Use round() when scaling fixed parameter values
|
data/Rakefile
CHANGED
data/ext/Blob.c
CHANGED
@@ -100,13 +100,12 @@ static VALUE getBlobData(VALUE self) {
|
|
100
100
|
Data_Get_Struct(self, BlobHandle, blob);
|
101
101
|
if(blob->size > 0) {
|
102
102
|
char *buffer = loadBlobData(blob);
|
103
|
-
|
104
103
|
if(buffer != NULL) {
|
105
104
|
data = rfbstr(connection, blob->charset, buffer, blob->size);
|
105
|
+
free(buffer);
|
106
|
+
rb_iv_set(self, "@data", data);
|
106
107
|
}
|
107
|
-
free(buffer);
|
108
108
|
}
|
109
|
-
rb_iv_set(self, "@data", data);
|
110
109
|
}
|
111
110
|
|
112
111
|
return(data);
|
data/ext/Row.c
CHANGED
@@ -58,6 +58,43 @@ static VALUE rowValuesAt(int, VALUE *, VALUE);
|
|
58
58
|
/* Globals. */
|
59
59
|
VALUE cRow;
|
60
60
|
|
61
|
+
/**
|
62
|
+
* This function integrates with the Ruby garbage collector to insure that
|
63
|
+
* all resources associated with a Row object are marked during the mark phase
|
64
|
+
*
|
65
|
+
* @param row A pointer to the RowHandle object for the Row object.
|
66
|
+
*
|
67
|
+
*/
|
68
|
+
void rowGCMark(void *handle) {
|
69
|
+
if(handle != NULL) {
|
70
|
+
RowHandle *row = (RowHandle *)handle;
|
71
|
+
int i;
|
72
|
+
for(i = 0; i < row->size; i++) {
|
73
|
+
rb_gc_mark(row->columns[i].value);
|
74
|
+
rb_gc_mark(row->columns[i].type);
|
75
|
+
rb_gc_mark(row->columns[i].scale);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* This function integrates with the Ruby garbage collector to insure that
|
82
|
+
* all resources associated with a Row object are released whenever the Row
|
83
|
+
* object is collected.
|
84
|
+
*
|
85
|
+
* @param row A pointer to the RowHandle object for the Row object.
|
86
|
+
*
|
87
|
+
*/
|
88
|
+
void freeRow(void *row) {
|
89
|
+
if(row != NULL) {
|
90
|
+
RowHandle *handle = (RowHandle *)row;
|
91
|
+
|
92
|
+
if(handle->columns != NULL) {
|
93
|
+
free(handle->columns);
|
94
|
+
}
|
95
|
+
free(handle);
|
96
|
+
}
|
97
|
+
}
|
61
98
|
|
62
99
|
/**
|
63
100
|
* This function integrates with the Ruby memory allocation system to allocate
|
@@ -77,7 +114,7 @@ static VALUE allocateRow(VALUE klass) {
|
|
77
114
|
handle->size = 0;
|
78
115
|
handle->number = 0;
|
79
116
|
handle->columns = NULL;
|
80
|
-
row = Data_Wrap_Struct(klass,
|
117
|
+
row = Data_Wrap_Struct(klass, rowGCMark, freeRow, handle);
|
81
118
|
} else {
|
82
119
|
/* Generate an exception. */
|
83
120
|
rb_raise(rb_eNoMemError, "Memory allocation failure allocating a row.");
|
@@ -816,26 +853,6 @@ VALUE rowValuesAt(int size, VALUE *keys, VALUE self) {
|
|
816
853
|
}
|
817
854
|
|
818
855
|
|
819
|
-
/**
|
820
|
-
* This function integrates with the Ruby garbage collector to insure that
|
821
|
-
* all resources associated with a Row object are released whenever the Row
|
822
|
-
* object is collected.
|
823
|
-
*
|
824
|
-
* @param row A pointer to the RowHandle object for the Row object.
|
825
|
-
*
|
826
|
-
*/
|
827
|
-
void freeRow(void *row) {
|
828
|
-
if(row != NULL) {
|
829
|
-
RowHandle *handle = (RowHandle *)row;
|
830
|
-
|
831
|
-
if(handle->columns != NULL) {
|
832
|
-
free(handle->columns);
|
833
|
-
}
|
834
|
-
free(handle);
|
835
|
-
}
|
836
|
-
}
|
837
|
-
|
838
|
-
|
839
856
|
/**
|
840
857
|
* This function provides a programmatic means of creating a Row object.
|
841
858
|
*
|
data/ext/Row.h
CHANGED
data/ext/Statement.c
CHANGED
@@ -45,6 +45,7 @@ static VALUE execAndCloseStatement(int, VALUE*, VALUE);
|
|
45
45
|
static VALUE closeStatement(VALUE);
|
46
46
|
static VALUE getStatementPrepared(VALUE);
|
47
47
|
static VALUE prepareStatement(int, VALUE*, VALUE);
|
48
|
+
static VALUE getStatementPlan(VALUE);
|
48
49
|
|
49
50
|
VALUE execAndManageTransaction(VALUE, VALUE, VALUE);
|
50
51
|
VALUE execAndManageStatement(VALUE, VALUE, VALUE);
|
@@ -687,6 +688,48 @@ static VALUE prepareStatement(int argc, VALUE *argv, VALUE self) {
|
|
687
688
|
return (self);
|
688
689
|
}
|
689
690
|
|
691
|
+
/**
|
692
|
+
* This function provides the plan method for the Statement class.
|
693
|
+
*
|
694
|
+
* @param self A reference to the Statement object to call the method on.
|
695
|
+
*
|
696
|
+
* @return Query plan
|
697
|
+
*
|
698
|
+
*/
|
699
|
+
VALUE getStatementPlan(VALUE self) {
|
700
|
+
StatementHandle *statement = getPreparedHandle(self);
|
701
|
+
ISC_STATUS status[ISC_STATUS_LENGTH];
|
702
|
+
unsigned int dataLength = 1024;
|
703
|
+
unsigned short retry = 1;
|
704
|
+
VALUE result = Qnil;
|
705
|
+
char items[] = {isc_info_sql_get_plan};
|
706
|
+
char *buffer = ALLOC_N(char, dataLength);
|
707
|
+
while(retry == 1) {
|
708
|
+
retry = 0;
|
709
|
+
if(!isc_dsql_sql_info(status, &statement->handle, sizeof(items), items,
|
710
|
+
dataLength, buffer)) {
|
711
|
+
switch(buffer[0]) {
|
712
|
+
case isc_info_truncated:
|
713
|
+
dataLength = dataLength + 1024;
|
714
|
+
buffer = REALLOC_N(buffer, char, dataLength);
|
715
|
+
retry = 1;
|
716
|
+
break;
|
717
|
+
case isc_info_sql_get_plan:
|
718
|
+
dataLength = isc_vax_integer(&buffer[1], 2);
|
719
|
+
result = rb_str_new(&buffer[3], dataLength);
|
720
|
+
rb_funcall(result, rb_intern("strip!"), 0);
|
721
|
+
default:
|
722
|
+
retry = 0;
|
723
|
+
}
|
724
|
+
}
|
725
|
+
}
|
726
|
+
free(buffer);
|
727
|
+
if (result == Qnil) {
|
728
|
+
rb_fireruby_raise(status, "Error retrieving query plan.");
|
729
|
+
}
|
730
|
+
return (result);
|
731
|
+
}
|
732
|
+
|
690
733
|
/**
|
691
734
|
* This function provides a programmatic means of creating a Statement object.
|
692
735
|
*
|
@@ -797,6 +840,7 @@ void Init_Statement(VALUE module) {
|
|
797
840
|
rb_define_method(cStatement, "parameter_count", getStatementParameterCount, 0);
|
798
841
|
rb_define_method(cStatement, "prepare", prepareStatement, -1);
|
799
842
|
rb_define_method(cStatement, "prepared?", getStatementPrepared, 0);
|
843
|
+
rb_define_method(cStatement, "plan", getStatementPlan, 0);
|
800
844
|
|
801
845
|
rb_define_const(cStatement, "SELECT_STATEMENT",
|
802
846
|
INT2FIX(isc_info_sql_stmt_select));
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Author: Ken Kunz <kennethkunz@gmail.com>
|
2
2
|
require 'digest/sha1'
|
3
3
|
require 'active_record/connection_adapters/abstract_adapter'
|
4
|
-
require 'active_support/core_ext/kernel/requires'
|
5
4
|
require 'rubyfb_options'
|
6
5
|
|
7
6
|
if defined?(Arel) then
|
@@ -332,6 +331,7 @@ module ActiveRecord
|
|
332
331
|
@transaction = nil
|
333
332
|
@blobs_disabled = 0
|
334
333
|
@statements = {}
|
334
|
+
@visitor = Arel::Visitors::RubyFB.new self if defined?(Arel::Visitors::RubyFB)
|
335
335
|
end
|
336
336
|
|
337
337
|
def self.visitor_for(pool) # :nodoc:
|
@@ -516,12 +516,17 @@ module ActiveRecord
|
|
516
516
|
end
|
517
517
|
s = cache || @connection.create_statement(sql)
|
518
518
|
s.prepare(@transaction) unless s.prepared?
|
519
|
+
|
519
520
|
if Rubyfb::Statement::DDL_STATEMENT == s.type
|
520
521
|
clear_cache!
|
521
522
|
elsif cache.nil? && !binds.empty?
|
522
523
|
@statements[sql] = cache = s
|
523
524
|
end
|
524
|
-
if
|
525
|
+
if name == 'EXPLAIN'
|
526
|
+
return s.plan.tap do
|
527
|
+
s.close unless cache
|
528
|
+
end
|
529
|
+
elsif cache
|
525
530
|
s.exec(binds, @transaction, &block)
|
526
531
|
else
|
527
532
|
s.exec_and_close(binds, @transaction, &block)
|
@@ -952,7 +957,7 @@ module ActiveRecord
|
|
952
957
|
end
|
953
958
|
|
954
959
|
def change_column_type(table_name, column_name, type, options = {})
|
955
|
-
sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit])}"
|
960
|
+
sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
956
961
|
exec_query(sql)
|
957
962
|
rescue StatementInvalid
|
958
963
|
raise unless non_existent_domain_error?
|
@@ -1084,6 +1089,14 @@ module ActiveRecord
|
|
1084
1089
|
end
|
1085
1090
|
|
1086
1091
|
class RubyfbAR31Adapter < RubyfbAdapter
|
1092
|
+
def supports_explain?
|
1093
|
+
true
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
def explain(arel, binds = [])
|
1097
|
+
exec_query(to_sql(arel), 'EXPLAIN', binds)
|
1098
|
+
end
|
1099
|
+
|
1087
1100
|
protected
|
1088
1101
|
def log(sql, name, binds = nil) #:nodoc:
|
1089
1102
|
super sql, name, binds
|
data/lib/rubyfb_lib.so
CHANGED
Binary file
|
data/lib/src.rb
CHANGED
@@ -712,6 +712,15 @@ module Rubyfb
|
|
712
712
|
#
|
713
713
|
def close
|
714
714
|
end
|
715
|
+
|
716
|
+
#
|
717
|
+
# This method returns the SQL execution plan for the statement
|
718
|
+
#
|
719
|
+
# ==== Exceptions
|
720
|
+
# FireRubyError:: Generated whenever a problem occurs obtaining the plan
|
721
|
+
#
|
722
|
+
def plan
|
723
|
+
end
|
715
724
|
end
|
716
725
|
|
717
726
|
|
@@ -1509,6 +1518,7 @@ module Rubyfb
|
|
1509
1518
|
#
|
1510
1519
|
# This method is used to set the indicator for whether checksum values
|
1511
1520
|
# should be ignored in performing a backup.
|
1521
|
+
|
1512
1522
|
#
|
1513
1523
|
# ==== Parameters
|
1514
1524
|
# setting:: True to ignore checksums, false otherwise.
|
data/rubyfb.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "rubyfb"
|
5
|
-
s.version = "0.6.
|
5
|
+
s.version = "0.6.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["George Georgiev"]
|
9
|
-
s.date = "2012-
|
9
|
+
s.date = "2012-02-21"
|
10
10
|
s.description = "Firebird SQL access library"
|
11
11
|
s.email = "georgiev@heatbs.com"
|
12
12
|
s.extensions = ["ext/extconf.rb"]
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rubyfb", "--main", "README"]
|
17
17
|
s.require_paths = ["lib", "ext"]
|
18
18
|
s.rubyforge_project = "rubyfb"
|
19
|
-
s.rubygems_version = "1.8.
|
19
|
+
s.rubygems_version = "1.8.11"
|
20
20
|
s.summary = "Firebird SQL access library"
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
data/test/StatementTest.rb
CHANGED
@@ -149,4 +149,14 @@ class StatementTest < Test::Unit::TestCase
|
|
149
149
|
cxn.execute_immediate('DROP TABLE STRING_TEST')
|
150
150
|
end
|
151
151
|
end
|
152
|
+
|
153
|
+
def test05
|
154
|
+
@database.connect(DB_USER_NAME, DB_PASSWORD) do |cxn|
|
155
|
+
cxn.execute_immediate('CREATE TABLE PLAN_TEST(TEXT VARCHAR(100) CHARACTER SET UTF8)')
|
156
|
+
s = cxn.create_statement('SELECT * FROM PLAN_TEST')
|
157
|
+
assert_equal("PLAN (PLAN_TEST NATURAL)", s.plan)
|
158
|
+
s.close
|
159
|
+
cxn.execute_immediate('DROP TABLE PLAN_TEST')
|
160
|
+
end
|
161
|
+
end
|
152
162
|
end
|
metadata
CHANGED
@@ -1,30 +1,22 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyfb
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.3
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 6
|
9
|
-
- 2
|
10
|
-
version: 0.6.2
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- George Georgiev
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2012-01-04 00:00:00 Z
|
12
|
+
date: 2012-02-21 00:00:00.000000000 Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
14
|
description: Firebird SQL access library
|
22
15
|
email: georgiev@heatbs.com
|
23
16
|
executables: []
|
24
|
-
|
25
|
-
extensions:
|
17
|
+
extensions:
|
26
18
|
- ext/extconf.rb
|
27
|
-
extra_rdoc_files:
|
19
|
+
extra_rdoc_files:
|
28
20
|
- CHANGELOG
|
29
21
|
- LICENSE
|
30
22
|
- README
|
@@ -36,7 +28,7 @@ extra_rdoc_files:
|
|
36
28
|
- lib/rubyfb.rb
|
37
29
|
- lib/rubyfb_options.rb
|
38
30
|
- lib/src.rb
|
39
|
-
files:
|
31
|
+
files:
|
40
32
|
- CHANGELOG
|
41
33
|
- LICENSE
|
42
34
|
- Manifest
|
@@ -128,43 +120,33 @@ files:
|
|
128
120
|
- rubyfb.gemspec
|
129
121
|
homepage: http://rubyforge.org/projects/rubyfb
|
130
122
|
licenses: []
|
131
|
-
|
132
123
|
post_install_message:
|
133
|
-
rdoc_options:
|
124
|
+
rdoc_options:
|
134
125
|
- --line-numbers
|
135
126
|
- --inline-source
|
136
127
|
- --title
|
137
128
|
- Rubyfb
|
138
129
|
- --main
|
139
130
|
- README
|
140
|
-
require_paths:
|
131
|
+
require_paths:
|
141
132
|
- lib
|
142
133
|
- ext
|
143
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
135
|
none: false
|
145
|
-
requirements:
|
146
|
-
- -
|
147
|
-
- !ruby/object:Gem::Version
|
148
|
-
|
149
|
-
|
150
|
-
- 0
|
151
|
-
version: "0"
|
152
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
141
|
none: false
|
154
|
-
requirements:
|
155
|
-
- -
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
|
158
|
-
segments:
|
159
|
-
- 1
|
160
|
-
- 2
|
161
|
-
version: "1.2"
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.2'
|
162
146
|
requirements: []
|
163
|
-
|
164
147
|
rubyforge_project: rubyfb
|
165
|
-
rubygems_version: 1.8.
|
148
|
+
rubygems_version: 1.8.11
|
166
149
|
signing_key:
|
167
150
|
specification_version: 3
|
168
151
|
summary: Firebird SQL access library
|
169
152
|
test_files: []
|
170
|
-
|