sqlpostgres 1.2.6 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +18 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +12 -0
- data/README.rdoc +5 -2
- data/Rakefile +5 -24
- data/VERSION +1 -1
- data/lib/sqlpostgres/Connection.rb +8 -3
- data/lib/sqlpostgres/Cursor.rb +2 -2
- data/lib/sqlpostgres/Insert.rb +1 -1
- data/lib/sqlpostgres/PgBit.rb +1 -1
- data/lib/sqlpostgres/PgBox.rb +1 -1
- data/lib/sqlpostgres/PgCidr.rb +1 -1
- data/lib/sqlpostgres/PgCircle.rb +1 -1
- data/lib/sqlpostgres/PgInet.rb +1 -1
- data/lib/sqlpostgres/PgInterval.rb +1 -1
- data/lib/sqlpostgres/PgLineSegment.rb +1 -1
- data/lib/sqlpostgres/PgMacAddr.rb +1 -1
- data/lib/sqlpostgres/PgPath.rb +1 -1
- data/lib/sqlpostgres/PgPoint.rb +1 -1
- data/lib/sqlpostgres/PgPolygon.rb +1 -1
- data/lib/sqlpostgres/PgTime.rb +1 -1
- data/lib/sqlpostgres/PgTimeWithTimeZone.rb +1 -1
- data/lib/sqlpostgres/PgTimestamp.rb +1 -1
- data/lib/sqlpostgres/PgTwoPoints.rb +1 -1
- data/lib/sqlpostgres/PgWrapper.rb +1 -1
- data/lib/sqlpostgres/Select.rb +25 -25
- data/lib/sqlpostgres/Translate.rb +7 -29
- data/lib/sqlpostgres/Update.rb +1 -1
- data/rake_tasks/db.rake +17 -0
- data/rake_tasks/default.rake +1 -0
- data/rake_tasks/jeweler.rake +18 -0
- data/rake_tasks/test.rake +2 -0
- data/rake_tasks/test_spec.rake +3 -0
- data/rake_tasks/test_unit.rake +4 -0
- data/spec/Translate_spec.rb +533 -0
- data/spec/config/.gitignore +1 -0
- data/spec/config/config.yml +10 -0
- data/spec/config/database.yml.template +6 -0
- data/spec/connection_spec.rb +515 -0
- data/spec/cursor_spec.rb +288 -0
- data/spec/lib/database_config.rb +33 -0
- data/spec/lib/database_server.rb +42 -0
- data/spec/lib/postgres_template.rb +60 -0
- data/spec/lib/target_database_servers.rb +55 -0
- data/spec/lib/temporary_table.rb +45 -0
- data/spec/lib/test_config.rb +24 -0
- data/spec/lib/test_connection.rb +29 -0
- data/spec/lib/test_database.rb +57 -0
- data/spec/roundtrip_spec.rb +582 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/all_characters.rb +18 -0
- data/spec/support/clear_default_connection.rb +5 -0
- data/spec/support/temporary_table.rb +24 -0
- data/spec/support/test_connections.rb +10 -0
- data/sqlpostgres.gemspec +35 -4
- data/test/Connection.test.rb +7 -5
- data/test/Select.test.rb +1 -1
- data/test/TestConfig.rb +9 -0
- data/test/TestUtil.rb +17 -3
- metadata +66 -9
- data/test/Translate.test.rb +0 -354
- data/test/roundtrip.test.rb +0 -565
data/Changelog.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
### 1.3.0
|
2
|
+
|
3
|
+
Enhancements
|
4
|
+
|
5
|
+
* Support Postgresql 9
|
6
|
+
* Some tests converted to rspec
|
7
|
+
* Connection can set client encoding
|
8
|
+
* More adaptable configuration for databases to run tests against
|
9
|
+
|
10
|
+
### 1.2.6
|
11
|
+
|
12
|
+
Bug fixes
|
13
|
+
|
14
|
+
* DateTime objects store their full precision
|
15
|
+
|
16
|
+
### 1.2.4
|
17
|
+
|
18
|
+
* First public release
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
diff-lcs (1.1.3)
|
4
5
|
git (1.2.5)
|
5
6
|
jeweler (1.8.4)
|
6
7
|
bundler (~> 1.0)
|
@@ -8,15 +9,26 @@ GEM
|
|
8
9
|
rake
|
9
10
|
rdoc
|
10
11
|
json (1.7.6)
|
12
|
+
memoizer (1.0.1)
|
11
13
|
pg (0.13.2)
|
12
14
|
rake (10.0.3)
|
13
15
|
rdoc (3.12)
|
14
16
|
json (~> 1.4)
|
17
|
+
rspec (2.12.0)
|
18
|
+
rspec-core (~> 2.12.0)
|
19
|
+
rspec-expectations (~> 2.12.0)
|
20
|
+
rspec-mocks (~> 2.12.0)
|
21
|
+
rspec-core (2.12.2)
|
22
|
+
rspec-expectations (2.12.1)
|
23
|
+
diff-lcs (~> 1.1.3)
|
24
|
+
rspec-mocks (2.12.1)
|
15
25
|
|
16
26
|
PLATFORMS
|
17
27
|
ruby
|
18
28
|
|
19
29
|
DEPENDENCIES
|
20
30
|
jeweler (~> 1.8.4)
|
31
|
+
memoizer (~> 1.0.1)
|
21
32
|
pg (~> 0.13.2)
|
22
33
|
rake (~> 10.0.3)
|
34
|
+
rspec (~> 2.12.0)
|
data/README.rdoc
CHANGED
@@ -47,8 +47,7 @@ The tests are known to pass in MRI 1.8.7 and MRI 1.9.3
|
|
47
47
|
|
48
48
|
== POSTGRES VERSIONS
|
49
49
|
|
50
|
-
This library works with Postgres 1.8
|
51
|
-
Postgres 1.9.
|
50
|
+
This library works with Postgres 1.8 and Postgres 1.9.
|
52
51
|
|
53
52
|
== ENCODINGS
|
54
53
|
|
@@ -57,3 +56,7 @@ This library only works properly with the SQL-ASCII encoding.
|
|
57
56
|
== WHOAMI
|
58
57
|
|
59
58
|
Wayne Conrad <wconrad@yagni.com>
|
59
|
+
|
60
|
+
== CONTRIBUTORS
|
61
|
+
|
62
|
+
Sam Kellogg <sam@nickstoys.com>
|
data/Rakefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
|
5
4
|
require 'bundler'
|
5
|
+
|
6
6
|
begin
|
7
7
|
Bundler.setup(:default, :development)
|
8
8
|
rescue Bundler::BundlerError => e
|
@@ -10,28 +10,9 @@ rescue Bundler::BundlerError => e
|
|
10
10
|
$stderr.puts 'Run `bundle install` to install missing gems'
|
11
11
|
exit e.status_code
|
12
12
|
end
|
13
|
-
require 'rake'
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
# gem is a Gem::Specification... see
|
18
|
-
# http://docs.rubygems.org/read/chapter/20 for more options
|
19
|
-
gem.name = 'sqlpostgres'
|
20
|
-
gem.homepage = 'http://github.com/wconrad/sqlpostgres'
|
21
|
-
gem.license = 'MIT'
|
22
|
-
gem.summary = %Q{library for postgresql queries}
|
23
|
-
gem.description =
|
24
|
-
('A mini-language for building and executing SQL statements '\
|
25
|
-
'against a postgresql database. This is a very old library, '\
|
26
|
-
'pre-dating active record and lacking many of its refinments. '\
|
27
|
-
'New projects will probably not want to use it.')
|
28
|
-
gem.email = 'wconrad@yagni.com'
|
29
|
-
gem.authors = ['Wayne Conrad']
|
30
|
-
# dependencies defined in Gemfile
|
31
|
-
end
|
32
|
-
Jeweler::RubygemsDotOrgTasks.new
|
14
|
+
$:.unshift(File.dirname(__FILE__) + '/lib')
|
15
|
+
Dir['rake_tasks/**/*.rake'].sort.each { |path| load path }
|
33
16
|
|
34
|
-
|
35
|
-
|
36
|
-
system 'test/test'
|
37
|
-
end
|
17
|
+
require File.expand_path('spec/lib/target_database_servers',
|
18
|
+
File.dirname(__FILE__))
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.3.0
|
@@ -83,6 +83,8 @@ module SqlPostgres
|
|
83
83
|
# to nil.
|
84
84
|
# 'password'::
|
85
85
|
# Password. nil, the default, means no password.
|
86
|
+
# 'encoding'::
|
87
|
+
# Client encoding.
|
86
88
|
#
|
87
89
|
# To wrap an existing connection, pass this argument:
|
88
90
|
#
|
@@ -107,12 +109,15 @@ module SqlPostgres
|
|
107
109
|
tty = args['tty'] || ""
|
108
110
|
login = args['login']
|
109
111
|
password = args['password']
|
112
|
+
client_encoding = args['encoding']
|
110
113
|
@pgconn = @@pgClass.connect(hostName, port, options, tty, dbName,
|
111
114
|
login, password)
|
115
|
+
if client_encoding
|
116
|
+
@pgconn.set_client_encoding(client_encoding)
|
117
|
+
end
|
112
118
|
end
|
113
119
|
@statement_in_exception = args['statement_in_exception']
|
114
120
|
@statement_in_exception = true if @statement_in_exception.nil?
|
115
|
-
@pgconn.set_client_encoding("unicode")
|
116
121
|
end
|
117
122
|
|
118
123
|
# close the connection. If it's already closed, do nothing.
|
@@ -177,8 +182,8 @@ module SqlPostgres
|
|
177
182
|
unless column.converter.nil?
|
178
183
|
typeCode = pgresult.ftype(i)
|
179
184
|
value = row[i]
|
180
|
-
args = [value]
|
181
|
-
args << typeCode if column.converter.arity ==
|
185
|
+
args = [value, @pgconn]
|
186
|
+
args << typeCode if column.converter.arity == 3
|
182
187
|
hash[column.as || column.value] =
|
183
188
|
value && column.converter.call(*args)
|
184
189
|
end
|
data/lib/sqlpostgres/Cursor.rb
CHANGED
@@ -101,8 +101,8 @@ module SqlPostgres
|
|
101
101
|
@connection.exec(statement)
|
102
102
|
end
|
103
103
|
|
104
|
-
# Close the cursor. Once closed, it may closed or fetched
|
105
|
-
# again.
|
104
|
+
# Close the cursor. Once closed, it may not be closed or fetched
|
105
|
+
# from again.
|
106
106
|
|
107
107
|
def close
|
108
108
|
statement = "close #{@name}"
|
data/lib/sqlpostgres/Insert.rb
CHANGED
@@ -140,7 +140,7 @@ module SqlPostgres
|
|
140
140
|
|
141
141
|
def insert_bytea(column, value = :no_value)
|
142
142
|
@columns << column
|
143
|
-
@values << Translate.escape_bytea(value) unless value == :no_value
|
143
|
+
@values << Translate.escape_bytea(value, @connection.pgconn) unless value == :no_value
|
144
144
|
end
|
145
145
|
|
146
146
|
# Insert into a bytea[] (bytea array) column. You must use this
|
data/lib/sqlpostgres/PgBit.rb
CHANGED
data/lib/sqlpostgres/PgBox.rb
CHANGED
data/lib/sqlpostgres/PgCidr.rb
CHANGED
data/lib/sqlpostgres/PgCircle.rb
CHANGED
data/lib/sqlpostgres/PgInet.rb
CHANGED
data/lib/sqlpostgres/PgPath.rb
CHANGED
data/lib/sqlpostgres/PgPoint.rb
CHANGED
data/lib/sqlpostgres/PgTime.rb
CHANGED
data/lib/sqlpostgres/Select.rb
CHANGED
@@ -609,29 +609,29 @@ module SqlPostgres
|
|
609
609
|
|
610
610
|
# Converters used to translate strings into Ruby types.
|
611
611
|
|
612
|
-
BitConverter = proc { |s| PgBit.from_sql(s) }
|
613
|
-
BooleanConverter = proc { |s| s == 't' }
|
614
|
-
BoxConverter = proc { |s| PgBox.from_sql(s) }
|
615
|
-
ByteaConverter = proc { |s| Translate.unescape_bytea(s) }
|
616
|
-
CidrConverter = proc { |s| PgCidr.from_sql(s) }
|
617
|
-
CircleConverter = proc { |s| PgCircle.from_sql(s) }
|
618
|
-
DateConverter = proc { |s| Translate.sql_to_date(s) }
|
619
|
-
FloatConverter = proc { |s| s.to_f }
|
620
|
-
InetConverter = proc { |s| PgInet.from_sql(s) }
|
621
|
-
IntegerConverter = proc { |s| s.to_i }
|
622
|
-
IntervalConverter = proc { |s| PgInterval.from_sql(s) }
|
623
|
-
LsegConverter = proc { |s| PgLineSegment.from_sql(s) }
|
624
|
-
MacAddrConverter = proc { |s| PgMacAddr.from_sql(s) }
|
625
|
-
PathConverter = proc { |s| PgPath.from_sql(s) }
|
626
|
-
PointConverter = proc { |s| PgPoint.from_sql(s) }
|
627
|
-
PolygonConverter = proc { |s| PgPolygon.from_sql(s) }
|
628
|
-
QCharConverter = proc { |s| Translate.unescape_qchar(s) }
|
629
|
-
StringConverter = proc { |s| s }
|
630
|
-
TimeConverter = proc { |s| PgTime.from_sql(s) }
|
631
|
-
TimeStringConverter = proc { |s| Time.local(*s.split(/:/)) }
|
632
|
-
TimeWithTimeZoneConverter = proc { |s| PgTimeWithTimeZone.from_sql(s) }
|
633
|
-
TimestampConverter = proc { |s| PgTimestamp.from_sql(s) }
|
634
|
-
TimestampTzConverter = proc { |s| Translate.sql_to_datetime(s) }
|
612
|
+
BitConverter = proc { |s, server_version| PgBit.from_sql(s) }
|
613
|
+
BooleanConverter = proc { |s, server_version| s == 't' }
|
614
|
+
BoxConverter = proc { |s, server_version| PgBox.from_sql(s) }
|
615
|
+
ByteaConverter = proc { |s, server_version| Translate.unescape_bytea(s, server_version) }
|
616
|
+
CidrConverter = proc { |s, server_version| PgCidr.from_sql(s) }
|
617
|
+
CircleConverter = proc { |s, server_version| PgCircle.from_sql(s) }
|
618
|
+
DateConverter = proc { |s, server_version| Translate.sql_to_date(s) }
|
619
|
+
FloatConverter = proc { |s, server_version| s.to_f }
|
620
|
+
InetConverter = proc { |s, server_version| PgInet.from_sql(s) }
|
621
|
+
IntegerConverter = proc { |s, server_version| s.to_i }
|
622
|
+
IntervalConverter = proc { |s, server_version| PgInterval.from_sql(s) }
|
623
|
+
LsegConverter = proc { |s, server_version| PgLineSegment.from_sql(s) }
|
624
|
+
MacAddrConverter = proc { |s, server_version| PgMacAddr.from_sql(s) }
|
625
|
+
PathConverter = proc { |s, server_version| PgPath.from_sql(s) }
|
626
|
+
PointConverter = proc { |s, server_version| PgPoint.from_sql(s) }
|
627
|
+
PolygonConverter = proc { |s, server_version| PgPolygon.from_sql(s) }
|
628
|
+
QCharConverter = proc { |s, server_version| Translate.unescape_qchar(s) }
|
629
|
+
StringConverter = proc { |s, server_version| s }
|
630
|
+
TimeConverter = proc { |s, server_version| PgTime.from_sql(s) }
|
631
|
+
TimeStringConverter = proc { |s, server_version| Time.local(*s.split(/:/)) }
|
632
|
+
TimeWithTimeZoneConverter = proc { |s, server_version| PgTimeWithTimeZone.from_sql(s) }
|
633
|
+
TimestampConverter = proc { |s, server_version| PgTimestamp.from_sql(s) }
|
634
|
+
TimestampTzConverter = proc { |s, server_version| Translate.sql_to_datetime(s) }
|
635
635
|
|
636
636
|
# Map each base (non-array) type to a converter.
|
637
637
|
|
@@ -705,7 +705,7 @@ module SqlPostgres
|
|
705
705
|
Types::ARRAY_VARCHAR => Types::VARCHAR,
|
706
706
|
}
|
707
707
|
|
708
|
-
AutoConverter = proc { |s, type_code|
|
708
|
+
AutoConverter = proc { |s, pgconn, type_code|
|
709
709
|
array_element_type = ARRAY_ELEMENT_TYPES[type_code]
|
710
710
|
if !array_element_type.nil?
|
711
711
|
s = Translate.sql_to_array(s)
|
@@ -713,7 +713,7 @@ module SqlPostgres
|
|
713
713
|
end
|
714
714
|
converter = CONVERTERS[type_code] || StringConverter
|
715
715
|
Translate.deep_collect(s) do |e|
|
716
|
-
converter.call(e)
|
716
|
+
converter.call(e, pgconn)
|
717
717
|
end
|
718
718
|
}
|
719
719
|
|
@@ -270,45 +270,23 @@ module SqlPostgres
|
|
270
270
|
# \
|
271
271
|
# \x7f-\xff
|
272
272
|
|
273
|
-
def escape_bytea(s)
|
273
|
+
def escape_bytea(s, pgconn)
|
274
274
|
return "null" if s.nil?
|
275
275
|
return "default" if s == :default
|
276
|
-
|
276
|
+
raise s.inspect if s.is_a?(Array) #DEBUG
|
277
|
+
value = "'" + pgconn.escape_bytea(s) + "'"
|
278
|
+
value = "E" + value if pgconn.server_version < 9_01_00
|
279
|
+
value
|
277
280
|
end
|
278
281
|
module_function :escape_bytea
|
279
282
|
|
280
|
-
# Unescape octal escape sequences, turning them back into bytes.
|
281
|
-
|
282
|
-
def unescape_octal_escapes(s)
|
283
|
-
s.gsub(/\\(\d{3})/) do
|
284
|
-
$1.oct.chr
|
285
|
-
end.gsub(/\\\\/, '\\')
|
286
|
-
end
|
287
|
-
module_function :unescape_octal_escapes
|
288
|
-
|
289
283
|
# Unescape a bytea string read from postgres.
|
290
284
|
|
291
|
-
def unescape_bytea(s)
|
292
|
-
|
293
|
-
s = s.force_encoding("ASCII-8BIT")
|
294
|
-
end
|
295
|
-
s.gsub(/\\(\\|[0-3][0-7][0-7])/) do
|
296
|
-
if $1 == "\\"
|
297
|
-
"\\"
|
298
|
-
else
|
299
|
-
$1.oct.chr
|
300
|
-
end
|
301
|
-
end
|
285
|
+
def unescape_bytea(s, pgconn)
|
286
|
+
pgconn.unescape_bytea(s)
|
302
287
|
end
|
303
288
|
module_function :unescape_bytea
|
304
289
|
|
305
|
-
# Unescape a text string read from postges.
|
306
|
-
|
307
|
-
def unescape_text(s)
|
308
|
-
unescape_bytea(s)
|
309
|
-
end
|
310
|
-
module_function :unescape_text
|
311
|
-
|
312
290
|
# Convert a time to SQL format, including microseconds:
|
313
291
|
# (YYYY-mm-dd HH:MM:SS.uuuuuu)
|
314
292
|
|
data/lib/sqlpostgres/Update.rb
CHANGED
@@ -99,7 +99,7 @@ module SqlPostgres
|
|
99
99
|
#**
|
100
100
|
|
101
101
|
def set_bytea(column, value)
|
102
|
-
@set_clauses << [column, Translate.escape_bytea(value)].join(' = ')
|
102
|
+
@set_clauses << [column, Translate.escape_bytea(value, @connection.pgconn)].join(' = ')
|
103
103
|
end
|
104
104
|
|
105
105
|
# Set a column to an array.
|
data/rake_tasks/db.rake
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace 'test:db' do
|
2
|
+
|
3
|
+
def target_database_servers
|
4
|
+
TestSupport::TargetDatabaseServers.instance
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Create test databases'
|
8
|
+
task 'create' do
|
9
|
+
target_database_servers.create_databases
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Drop test databases'
|
13
|
+
task 'drop' do
|
14
|
+
target_database_servers.drop_databases
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|