adapter-postgres 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in adapter-postgres.gemspec
4
+ gemspec
5
+
6
+ group(:development) do
7
+ gem 'jeweler'
8
+ gem 'yajl-ruby'
9
+ gem 'rspec', '~> 2.3'
10
+ gem 'log_buddy', '~> 0.5.0'
11
+ gem 'timecop', '~> 0.3.5'
12
+ gem 'i18n', '0.5.0'
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ adapter-postgres (0.1.1)
5
+ adapter-postgres
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.2)
11
+ git (1.2.5)
12
+ i18n (0.5.0)
13
+ jeweler (1.6.0)
14
+ bundler (~> 1.0.0)
15
+ git (>= 1.2.5)
16
+ rake
17
+ log_buddy (0.5.0)
18
+ rake (0.8.7)
19
+ rspec (2.4.0)
20
+ rspec-core (~> 2.4.0)
21
+ rspec-expectations (~> 2.4.0)
22
+ rspec-mocks (~> 2.4.0)
23
+ rspec-core (2.4.0)
24
+ rspec-expectations (2.4.0)
25
+ diff-lcs (~> 1.1.2)
26
+ rspec-mocks (2.4.0)
27
+ timecop (0.3.5)
28
+ yajl-ruby (0.7.9)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ adapter-postgres!
35
+ i18n (= 0.5.0)
36
+ jeweler
37
+ log_buddy (~> 0.5.0)
38
+ rspec (~> 2.3)
39
+ timecop (~> 0.3.5)
40
+ yajl-ruby
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 CLR
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,64 @@
1
+ = adapter-postgres
2
+
3
+ == DESCRIPTION:
4
+
5
+ Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter for more info on why
6
+ you would want to do this -- https://github.com/newtoy/adapter
7
+
8
+ == FEATURES/PROBLEMS:
9
+
10
+ This relies on the HSTORE data type in PostgreSQL. It will not work in MySQL, and HSTORE is as of
11
+ this writing delegated to the 'contribs' package of PostgreSQL, not the core package. See your
12
+ platform directions for installing 'contribs'.
13
+
14
+ Also note that implementation of HSTORE in v8.4 and v9+ are very different and probably exhibit
15
+ very different performance profiles.
16
+
17
+ == SYNOPSIS:
18
+
19
+ require 'adapter/postgres'
20
+
21
+ client = PGconn.connect("host=localhost port=5432 dbname=test user=#{user} password=#{pword}")
22
+ or
23
+ client = ActiveRecord::Base.connection.instance_variable_get("@connection")
24
+
25
+ adapter = Adapter[:postgres].new(client)
26
+ adapter['foo'] = 'bar'
27
+ etc...
28
+
29
+ See examples/ or specs/ for more examples.
30
+
31
+ == REQUIREMENTS:
32
+
33
+ PostgreSQL 8.4+ and PostgreSQL-contribs
34
+ pg or some other Ruby gem that provides a PGconn style connection to the database.
35
+
36
+ == INSTALL:
37
+
38
+ gem install adapter-postgres
39
+
40
+ You need to add the HSTORE data type to your database from contribs. If your contribs is installed
41
+ into /usl/share/pgsql/contrib, then as the user 'postgres' you might run:
42
+
43
+ psql database_name < /usr/share/pgsql/contrib/hstore.sql
44
+
45
+ This will give the database 'database_name' access to the HSTORE data type that the gem relies on.
46
+ There is a copy of 'hstore.sql' from PostgreSQL8.4 included in the 'examples' directory of this gem
47
+ for convenience.
48
+
49
+ Next, you need to create the table and one row for the data to be saved to. You will want to create
50
+ some kind of migration depending what kind of app you are working in that runs the following SQL
51
+ only once inside the database:
52
+
53
+ CREATE TABLE generic_hstore_table (data hstore);
54
+ INSERT INTO generic_hstore_table VALUES (''::hstore);
55
+
56
+ Now you can begin using the adapter. See the SYNOPSIS above.
57
+
58
+ == Note on Patches/Pull Requests
59
+
60
+ * Fork the project.
61
+ * Make your feature addition or bug fix.
62
+ * Add tests for it. This is important so we don't break it in a future version unintentionally.
63
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine, but bump version in a commit by itself so we can ignore when we pull)
64
+ * Send us a pull request. Bonus points for topic branches.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "adapter-postgres"
18
+ gem.homepage = "http://github.com/clr/adapter-postgres"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter for more info.}
21
+ gem.description = %Q{Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter for more info.}
22
+ gem.email = "clr@port49.com"
23
+ gem.authors = ["CLR"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rspec/core/rake_task'
31
+ RSpec::Core::RakeTask.new
32
+
33
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,73 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{adapter-postgres}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["CLR"]
12
+ s.date = %q{2011-05-18}
13
+ s.description = %q{Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter for more info.}
14
+ s.email = %q{clr@port49.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "adapter-postgres.gemspec",
28
+ "examples/hstore.sql",
29
+ "examples/postgres.rb",
30
+ "lib/adapter-postgres.rb",
31
+ "lib/adapter/postgres.rb",
32
+ "lib/adapter/postgres/version.rb",
33
+ "spec/helper.rb",
34
+ "spec/pg_testing_helper.rb",
35
+ "spec/postgres_spec.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/clr/adapter-postgres}
38
+ s.licenses = ["MIT"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.6.2}
41
+ s.summary = %q{Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter for more info.}
42
+
43
+ if s.respond_to? :specification_version then
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<adapter-postgres>, [">= 0"])
48
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
49
+ s.add_development_dependency(%q<yajl-ruby>, [">= 0"])
50
+ s.add_development_dependency(%q<rspec>, ["~> 2.3"])
51
+ s.add_development_dependency(%q<log_buddy>, ["~> 0.5.0"])
52
+ s.add_development_dependency(%q<timecop>, ["~> 0.3.5"])
53
+ s.add_development_dependency(%q<i18n>, ["= 0.5.0"])
54
+ else
55
+ s.add_dependency(%q<adapter-postgres>, [">= 0"])
56
+ s.add_dependency(%q<jeweler>, [">= 0"])
57
+ s.add_dependency(%q<yajl-ruby>, [">= 0"])
58
+ s.add_dependency(%q<rspec>, ["~> 2.3"])
59
+ s.add_dependency(%q<log_buddy>, ["~> 0.5.0"])
60
+ s.add_dependency(%q<timecop>, ["~> 0.3.5"])
61
+ s.add_dependency(%q<i18n>, ["= 0.5.0"])
62
+ end
63
+ else
64
+ s.add_dependency(%q<adapter-postgres>, [">= 0"])
65
+ s.add_dependency(%q<jeweler>, [">= 0"])
66
+ s.add_dependency(%q<yajl-ruby>, [">= 0"])
67
+ s.add_dependency(%q<rspec>, ["~> 2.3"])
68
+ s.add_dependency(%q<log_buddy>, ["~> 0.5.0"])
69
+ s.add_dependency(%q<timecop>, ["~> 0.3.5"])
70
+ s.add_dependency(%q<i18n>, ["= 0.5.0"])
71
+ end
72
+ end
73
+
@@ -0,0 +1,272 @@
1
+ /* $PostgreSQL: pgsql/contrib/hstore/hstore.sql.in,v 1.11.2.1 2010/06/22 11:36:28 rhaas Exp $ */
2
+
3
+ -- Adjust this setting to control where the objects get created.
4
+ SET search_path = public;
5
+
6
+ CREATE TYPE hstore;
7
+
8
+ CREATE OR REPLACE FUNCTION hstore_in(cstring)
9
+ RETURNS hstore
10
+ AS '$libdir/hstore'
11
+ LANGUAGE C STRICT;
12
+
13
+ CREATE OR REPLACE FUNCTION hstore_out(hstore)
14
+ RETURNS cstring
15
+ AS '$libdir/hstore'
16
+ LANGUAGE C STRICT;
17
+
18
+ CREATE TYPE hstore (
19
+ INTERNALLENGTH = -1,
20
+ INPUT = hstore_in,
21
+ OUTPUT = hstore_out,
22
+ STORAGE = extended
23
+ );
24
+
25
+ CREATE OR REPLACE FUNCTION fetchval(hstore,text)
26
+ RETURNS text
27
+ AS '$libdir/hstore'
28
+ LANGUAGE C STRICT IMMUTABLE;
29
+
30
+ CREATE OPERATOR -> (
31
+ LEFTARG = hstore,
32
+ RIGHTARG = text,
33
+ PROCEDURE = fetchval
34
+ );
35
+
36
+ CREATE OR REPLACE FUNCTION isexists(hstore,text)
37
+ RETURNS bool
38
+ AS '$libdir/hstore','exists'
39
+ LANGUAGE C STRICT IMMUTABLE;
40
+
41
+ CREATE OR REPLACE FUNCTION exist(hstore,text)
42
+ RETURNS bool
43
+ AS '$libdir/hstore','exists'
44
+ LANGUAGE C STRICT IMMUTABLE;
45
+
46
+ CREATE OPERATOR ? (
47
+ LEFTARG = hstore,
48
+ RIGHTARG = text,
49
+ PROCEDURE = exist,
50
+ RESTRICT = contsel,
51
+ JOIN = contjoinsel
52
+ );
53
+
54
+ CREATE OR REPLACE FUNCTION isdefined(hstore,text)
55
+ RETURNS bool
56
+ AS '$libdir/hstore','defined'
57
+ LANGUAGE C STRICT IMMUTABLE;
58
+
59
+ CREATE OR REPLACE FUNCTION defined(hstore,text)
60
+ RETURNS bool
61
+ AS '$libdir/hstore','defined'
62
+ LANGUAGE C STRICT IMMUTABLE;
63
+
64
+ CREATE OR REPLACE FUNCTION delete(hstore,text)
65
+ RETURNS hstore
66
+ AS '$libdir/hstore','delete'
67
+ LANGUAGE C STRICT IMMUTABLE;
68
+
69
+ CREATE OR REPLACE FUNCTION hs_concat(hstore,hstore)
70
+ RETURNS hstore
71
+ AS '$libdir/hstore'
72
+ LANGUAGE C STRICT IMMUTABLE;
73
+
74
+ CREATE OPERATOR || (
75
+ LEFTARG = hstore,
76
+ RIGHTARG = hstore,
77
+ PROCEDURE = hs_concat
78
+ );
79
+
80
+ CREATE OR REPLACE FUNCTION hs_contains(hstore,hstore)
81
+ RETURNS bool
82
+ AS '$libdir/hstore'
83
+ LANGUAGE C STRICT IMMUTABLE;
84
+
85
+ CREATE OR REPLACE FUNCTION hs_contained(hstore,hstore)
86
+ RETURNS bool
87
+ AS '$libdir/hstore'
88
+ LANGUAGE C STRICT IMMUTABLE;
89
+
90
+ CREATE OPERATOR @> (
91
+ LEFTARG = hstore,
92
+ RIGHTARG = hstore,
93
+ PROCEDURE = hs_contains,
94
+ COMMUTATOR = '<@',
95
+ RESTRICT = contsel,
96
+ JOIN = contjoinsel
97
+ );
98
+
99
+ CREATE OPERATOR <@ (
100
+ LEFTARG = hstore,
101
+ RIGHTARG = hstore,
102
+ PROCEDURE = hs_contained,
103
+ COMMUTATOR = '@>',
104
+ RESTRICT = contsel,
105
+ JOIN = contjoinsel
106
+ );
107
+
108
+ -- obsolete:
109
+ CREATE OPERATOR @ (
110
+ LEFTARG = hstore,
111
+ RIGHTARG = hstore,
112
+ PROCEDURE = hs_contains,
113
+ COMMUTATOR = '~',
114
+ RESTRICT = contsel,
115
+ JOIN = contjoinsel
116
+ );
117
+
118
+ CREATE OPERATOR ~ (
119
+ LEFTARG = hstore,
120
+ RIGHTARG = hstore,
121
+ PROCEDURE = hs_contained,
122
+ COMMUTATOR = '@',
123
+ RESTRICT = contsel,
124
+ JOIN = contjoinsel
125
+ );
126
+
127
+ CREATE OR REPLACE FUNCTION tconvert(text,text)
128
+ RETURNS hstore
129
+ AS '$libdir/hstore'
130
+ LANGUAGE C IMMUTABLE; -- not STRICT
131
+
132
+ -- For forward compatibility with PostgreSQL >= 9.0
133
+ CREATE OR REPLACE FUNCTION hstore(text,text)
134
+ RETURNS hstore
135
+ AS '$libdir/hstore', 'tconvert'
136
+ LANGUAGE C IMMUTABLE; -- not STRICT
137
+
138
+ CREATE OPERATOR => (
139
+ LEFTARG = text,
140
+ RIGHTARG = text,
141
+ PROCEDURE = tconvert
142
+ );
143
+
144
+ CREATE OR REPLACE FUNCTION akeys(hstore)
145
+ RETURNS _text
146
+ AS '$libdir/hstore'
147
+ LANGUAGE C STRICT IMMUTABLE;
148
+
149
+ CREATE OR REPLACE FUNCTION avals(hstore)
150
+ RETURNS _text
151
+ AS '$libdir/hstore'
152
+ LANGUAGE C STRICT IMMUTABLE;
153
+
154
+ CREATE OR REPLACE FUNCTION skeys(hstore)
155
+ RETURNS setof text
156
+ AS '$libdir/hstore'
157
+ LANGUAGE C STRICT IMMUTABLE;
158
+
159
+ CREATE OR REPLACE FUNCTION svals(hstore)
160
+ RETURNS setof text
161
+ AS '$libdir/hstore'
162
+ LANGUAGE C STRICT IMMUTABLE;
163
+
164
+ CREATE OR REPLACE FUNCTION each(IN hs hstore,
165
+ OUT key text,
166
+ OUT value text)
167
+ RETURNS SETOF record
168
+ AS '$libdir/hstore'
169
+ LANGUAGE C STRICT IMMUTABLE;
170
+
171
+
172
+
173
+ -- define the GiST support methods
174
+
175
+ CREATE TYPE ghstore;
176
+
177
+ CREATE OR REPLACE FUNCTION ghstore_in(cstring)
178
+ RETURNS ghstore
179
+ AS '$libdir/hstore'
180
+ LANGUAGE C STRICT;
181
+
182
+ CREATE OR REPLACE FUNCTION ghstore_out(ghstore)
183
+ RETURNS cstring
184
+ AS '$libdir/hstore'
185
+ LANGUAGE C STRICT;
186
+
187
+ CREATE TYPE ghstore (
188
+ INTERNALLENGTH = -1,
189
+ INPUT = ghstore_in,
190
+ OUTPUT = ghstore_out
191
+ );
192
+
193
+ CREATE OR REPLACE FUNCTION ghstore_compress(internal)
194
+ RETURNS internal
195
+ AS '$libdir/hstore'
196
+ LANGUAGE C IMMUTABLE STRICT;
197
+
198
+ CREATE OR REPLACE FUNCTION ghstore_decompress(internal)
199
+ RETURNS internal
200
+ AS '$libdir/hstore'
201
+ LANGUAGE C IMMUTABLE STRICT;
202
+
203
+ CREATE OR REPLACE FUNCTION ghstore_penalty(internal,internal,internal)
204
+ RETURNS internal
205
+ AS '$libdir/hstore'
206
+ LANGUAGE C IMMUTABLE STRICT;
207
+
208
+ CREATE OR REPLACE FUNCTION ghstore_picksplit(internal, internal)
209
+ RETURNS internal
210
+ AS '$libdir/hstore'
211
+ LANGUAGE C IMMUTABLE STRICT;
212
+
213
+ CREATE OR REPLACE FUNCTION ghstore_union(internal, internal)
214
+ RETURNS internal
215
+ AS '$libdir/hstore'
216
+ LANGUAGE C IMMUTABLE STRICT;
217
+
218
+ CREATE OR REPLACE FUNCTION ghstore_same(internal, internal, internal)
219
+ RETURNS internal
220
+ AS '$libdir/hstore'
221
+ LANGUAGE C IMMUTABLE STRICT;
222
+
223
+ CREATE OR REPLACE FUNCTION ghstore_consistent(internal,internal,int,oid,internal)
224
+ RETURNS bool
225
+ AS '$libdir/hstore'
226
+ LANGUAGE C IMMUTABLE STRICT;
227
+
228
+ -- register the opclass for indexing (not as default)
229
+ CREATE OPERATOR CLASS gist_hstore_ops
230
+ DEFAULT FOR TYPE hstore USING gist
231
+ AS
232
+ OPERATOR 7 @> ,
233
+ OPERATOR 9 ?(hstore,text) ,
234
+ --OPERATOR 8 <@ ,
235
+ OPERATOR 13 @ ,
236
+ --OPERATOR 14 ~ ,
237
+ FUNCTION 1 ghstore_consistent (internal, internal, int, oid, internal),
238
+ FUNCTION 2 ghstore_union (internal, internal),
239
+ FUNCTION 3 ghstore_compress (internal),
240
+ FUNCTION 4 ghstore_decompress (internal),
241
+ FUNCTION 5 ghstore_penalty (internal, internal, internal),
242
+ FUNCTION 6 ghstore_picksplit (internal, internal),
243
+ FUNCTION 7 ghstore_same (internal, internal, internal),
244
+ STORAGE ghstore;
245
+
246
+ -- define the GIN support methods
247
+
248
+ CREATE OR REPLACE FUNCTION gin_extract_hstore(internal, internal)
249
+ RETURNS internal
250
+ AS '$libdir/hstore'
251
+ LANGUAGE C IMMUTABLE STRICT;
252
+
253
+ CREATE OR REPLACE FUNCTION gin_extract_hstore_query(internal, internal, int2, internal, internal)
254
+ RETURNS internal
255
+ AS '$libdir/hstore'
256
+ LANGUAGE C IMMUTABLE STRICT;
257
+
258
+ CREATE OR REPLACE FUNCTION gin_consistent_hstore(internal, int2, internal, int4, internal, internal)
259
+ RETURNS bool
260
+ AS '$libdir/hstore'
261
+ LANGUAGE C IMMUTABLE STRICT;
262
+
263
+ CREATE OPERATOR CLASS gin_hstore_ops
264
+ DEFAULT FOR TYPE hstore USING gin
265
+ AS
266
+ OPERATOR 7 @> ,
267
+ OPERATOR 9 ?(hstore,text),
268
+ FUNCTION 1 bttextcmp(text,text),
269
+ FUNCTION 2 gin_extract_hstore(internal, internal),
270
+ FUNCTION 3 gin_extract_hstore_query(internal, internal, int2, internal, internal),
271
+ FUNCTION 4 gin_consistent_hstore(internal, int2, internal, int4, internal, internal),
272
+ STORAGE text;
@@ -0,0 +1,43 @@
1
+ # before attempting to 'require' this script into console, make sure
2
+ # you have 'adapter' in your Gemfile, and make sure you have the
3
+ # HSTORE data type available in your postgresql database. If you
4
+ # have permission and 'contribs' for postgres, you can add HSTORE
5
+ # with something like:
6
+ # psql database_name < /usr/share/pgsql/contrib/hstore.sql
7
+ # a copy of hstore.sql is kept in this examples directory as well.
8
+
9
+ require 'rubygems'
10
+ require 'pathname'
11
+
12
+ root_path = Pathname(__FILE__).dirname.join('..').expand_path
13
+ lib_path = root_path.join('lib')
14
+ $:.unshift(lib_path)
15
+
16
+ require 'adapter/postgres'
17
+
18
+ # say we are working inside of an existing Rails application
19
+ client = ActiveRecord::Base.connection.instance_variable_get("@connection")
20
+
21
+ # check and see if our table exists yet
22
+ table = client.exec("SELECT COUNT(relname) FROM pg_class WHERE relname='generic_hstore_table'").getvalue(0,0)
23
+ if table == 0
24
+ # then create the table we want and seed it
25
+ client.exec("CREATE TABLE generic_hstore_table (data hstore)")
26
+ client.exec("INSERT INTO generic_hstore_table VALUES (''::hstore)")
27
+ end
28
+
29
+ # start the adapter
30
+ adapter = Adapter[:postgres].new(client)
31
+ adapter.clear
32
+
33
+ adapter['foo'] = 'bar'
34
+ puts 'Should be bar: ' + adapter['foo'].inspect
35
+
36
+ adapter.delete('foo')
37
+ puts 'Should be nil: ' + adapter['foo'].inspect
38
+
39
+ adapter['foo'] = 'bar'
40
+ adapter.clear
41
+ puts 'Should be nil: ' + adapter['foo'].inspect
42
+
43
+ puts 'Should be bar: ' + adapter.fetch('foo', 'bar')
File without changes
@@ -0,0 +1,39 @@
1
+ require 'adapter'
2
+ require 'pg'
3
+
4
+ module Adapter
5
+ module Postgres
6
+ def table_name
7
+ "generic_hstore_table"
8
+ end
9
+
10
+ # I don't think this is ever used?
11
+ def key?(key)
12
+ res = client.exec("SELECT exist(data,'#{key_for(key)}') AS v FROM #{table_name}")
13
+ res.getvalue(0,0) != "f"
14
+ end
15
+
16
+ def read(key)
17
+ res = client.exec("SELECT data -> '#{key_for(key)}' AS v FROM #{table_name}")
18
+ decode(res.getvalue(0,0))
19
+ end
20
+
21
+ def write(key, value)
22
+ res = client.exec("UPDATE #{table_name} SET data = data || hstore('#{key_for(key)}','#{encode(value)}')")
23
+ value
24
+ end
25
+
26
+ def delete(key)
27
+ if value = read(key)
28
+ res = client.exec("UPDATE #{table_name} SET data = delete(data,'#{key_for(key)}')")
29
+ end
30
+ value
31
+ end
32
+
33
+ def clear
34
+ res = client.exec("UPDATE #{table_name} SET data = ''::hstore")
35
+ end
36
+ end
37
+ end
38
+
39
+ Adapter.define(:postgres, Adapter::Postgres)
@@ -0,0 +1,5 @@
1
+ module Adapter
2
+ module Postgres
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,27 @@
1
+ $:.unshift(File.expand_path('../../lib', __FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ Bundler.require(:default, :development)
7
+
8
+ require 'pathname'
9
+ require 'logger'
10
+
11
+ root_path = Pathname(__FILE__).dirname.join('..').expand_path
12
+ lib_path = root_path.join('lib')
13
+ log_path = root_path.join('log')
14
+ log_path.mkpath
15
+
16
+ require 'adapter/spec/an_adapter'
17
+ require 'adapter/spec/marshal_adapter'
18
+ require 'adapter/spec/json_adapter'
19
+ require 'adapter/spec/types'
20
+
21
+ require 'pg_testing_helper'
22
+
23
+ logger = Logger.new(log_path.join('test.log'))
24
+ LogBuddy.init(:logger => logger)
25
+
26
+ Rspec.configure do |c|
27
+ end
@@ -0,0 +1,227 @@
1
+ # This file is copied from ruby-pg
2
+
3
+ module PgTestingHelper
4
+
5
+
6
+ # Set some ANSI escape code constants (Shamelessly stolen from Perl's
7
+ # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
8
+ ANSI_ATTRIBUTES = {
9
+ 'clear' => 0,
10
+ 'reset' => 0,
11
+ 'bold' => 1,
12
+ 'dark' => 2,
13
+ 'underline' => 4,
14
+ 'underscore' => 4,
15
+ 'blink' => 5,
16
+ 'reverse' => 7,
17
+ 'concealed' => 8,
18
+
19
+ 'black' => 30, 'on_black' => 40,
20
+ 'red' => 31, 'on_red' => 41,
21
+ 'green' => 32, 'on_green' => 42,
22
+ 'yellow' => 33, 'on_yellow' => 43,
23
+ 'blue' => 34, 'on_blue' => 44,
24
+ 'magenta' => 35, 'on_magenta' => 45,
25
+ 'cyan' => 36, 'on_cyan' => 46,
26
+ 'white' => 37, 'on_white' => 47
27
+ }
28
+
29
+
30
+ ###############
31
+ module_function
32
+ ###############
33
+
34
+ ### Create a string that contains the ANSI codes specified and return it
35
+ def ansi_code( *attributes )
36
+ attributes.flatten!
37
+ attributes.collect! {|at| at.to_s }
38
+ # $stderr.puts "Returning ansicode for TERM = %p: %p" %
39
+ # [ ENV['TERM'], attributes ]
40
+ return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
41
+ attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
42
+
43
+ # $stderr.puts " attr is: %p" % [attributes]
44
+ if attributes.empty?
45
+ return ''
46
+ else
47
+ return "\e[%sm" % attributes
48
+ end
49
+ end
50
+
51
+
52
+ ### Colorize the given +string+ with the specified +attributes+ and return it, handling
53
+ ### line-endings, color reset, etc.
54
+ def colorize( *args )
55
+ string = ''
56
+
57
+ if block_given?
58
+ string = yield
59
+ else
60
+ string = args.shift
61
+ end
62
+
63
+ ending = string[/(\s)$/] || ''
64
+ string = string.rstrip
65
+
66
+ return ansi_code( args.flatten ) + string + ansi_code( 'reset' ) + ending
67
+ end
68
+
69
+
70
+ ### Output a message with highlighting.
71
+ def message( *msg )
72
+ $stderr.puts( colorize(:bold) { msg.flatten.join(' ') } )
73
+ end
74
+
75
+
76
+ ### Output a logging message if $VERBOSE is true
77
+ def trace( *msg )
78
+ return unless $VERBOSE
79
+ output = colorize( msg.flatten.join(' '), 'yellow' )
80
+ $stderr.puts( output )
81
+ end
82
+
83
+
84
+ ### Return the specified args as a string, quoting any that have a space.
85
+ def quotelist( *args )
86
+ return args.flatten.collect {|part| part.to_s =~ /\s/ ? part.to_s.inspect : part.to_s }
87
+ end
88
+
89
+
90
+ ### Run the specified command +cmd+ with system(), failing if the execution
91
+ ### fails.
92
+ def run( *cmd )
93
+ cmd.flatten!
94
+
95
+ if cmd.length > 1
96
+ trace( quotelist(*cmd) )
97
+ else
98
+ trace( cmd )
99
+ end
100
+
101
+ system( *cmd )
102
+ raise "Command failed: [%s]" % [cmd.join(' ')] unless $?.success?
103
+ end
104
+
105
+
106
+ NOFORK_PLATFORMS = %w{java}
107
+
108
+ ### Run the specified command +cmd+ after redirecting stdout and stderr to the specified
109
+ ### +logpath+, failing if the execution fails.
110
+ def log_and_run( logpath, *cmd )
111
+ cmd.flatten!
112
+
113
+ if cmd.length > 1
114
+ trace( quotelist(*cmd) )
115
+ else
116
+ trace( cmd )
117
+ end
118
+
119
+ # Eliminate the noise of creating/tearing down the database by
120
+ # redirecting STDERR/STDOUT to a logfile if the Ruby interpreter
121
+ # supports fork()
122
+ if NOFORK_PLATFORMS.include?( RUBY_PLATFORM )
123
+ system( *cmd )
124
+ else
125
+ logfh = File.open( logpath, File::WRONLY|File::CREAT|File::APPEND )
126
+ if pid = fork
127
+ logfh.close
128
+ else
129
+ $stdout.reopen( logfh )
130
+ $stderr.reopen( $stdout )
131
+ exec( *cmd )
132
+ $stderr.puts "After the exec()?!??!"
133
+ exit!
134
+ end
135
+
136
+ Process.wait( pid )
137
+ end
138
+
139
+ raise "Command failed: [%s]" % [cmd.join(' ')] unless $?.success?
140
+ end
141
+
142
+
143
+ ### Check the current directory for directories that look like they're
144
+ ### testing directories from previous tests, and tell any postgres instances
145
+ ### running in them to shut down.
146
+ def stop_existing_postmasters
147
+ # tmp_test_0.22329534700318
148
+ pat = Pathname.getwd + 'tmp_test_*'
149
+ Pathname.glob( pat.to_s ).each do |testdir|
150
+ datadir = testdir + 'data'
151
+ pidfile = datadir + 'postmaster.pid'
152
+ if pidfile.exist? && pid = pidfile.read.chomp.to_i
153
+ $stderr.puts "pidfile (%p) exists: %d" % [ pidfile, pid ]
154
+ begin
155
+ Process.kill( 0, pid )
156
+ rescue Errno::ESRCH
157
+ $stderr.puts "No postmaster running for %s" % [ datadir ]
158
+ # Process isn't alive, so don't try to stop it
159
+ else
160
+ $stderr.puts "Stopping lingering database at PID %d" % [ pid ]
161
+ run 'pg_ctl', '-D', datadir.to_s, '-m', 'fast', 'stop'
162
+ end
163
+ else
164
+ $stderr.puts "No pidfile (%p)" % [ pidfile ]
165
+ end
166
+ end
167
+ end
168
+
169
+
170
+ ### Set up a PostgreSQL database instance for testing.
171
+ def setup_testing_db( description )
172
+ require 'pg'
173
+ stop_existing_postmasters()
174
+
175
+ puts "Setting up test database for #{description} tests"
176
+ @test_directory = Pathname.getwd + "tmp_test_specs"
177
+ @test_pgdata = @test_directory + 'data'
178
+ @test_pgdata.mkpath
179
+
180
+ @port = 54321
181
+ ENV['PGPORT'] = @port.to_s
182
+ ENV['PGHOST'] = 'localhost'
183
+ @conninfo = "host=localhost port=#{@port} dbname=test"
184
+
185
+ @logfile = @test_directory + 'setup.log'
186
+ trace "Command output logged to #{@logfile}"
187
+
188
+ begin
189
+ unless (@test_pgdata+"postgresql.conf").exist?
190
+ FileUtils.rm_rf( @test_pgdata, :verbose => $DEBUG )
191
+ $stderr.puts "Running initdb"
192
+ log_and_run @logfile, 'initdb', '--no-locale', '-D', @test_pgdata.to_s
193
+ end
194
+
195
+ trace "Starting postgres"
196
+ log_and_run @logfile, 'pg_ctl', '-w', '-o', "-k #{@test_directory.to_s.inspect}",
197
+ '-D', @test_pgdata.to_s, 'start'
198
+ sleep 2
199
+
200
+ $stderr.puts "Creating the test DB"
201
+ log_and_run @logfile, 'psql', '-e', '-c', 'DROP DATABASE IF EXISTS test', 'postgres'
202
+ log_and_run @logfile, 'createdb', '-e', 'test'
203
+
204
+ rescue => err
205
+ $stderr.puts "%p during test setup: %s" % [ err.class, err.message ]
206
+ $stderr.puts "See #{@logfile} for details."
207
+ $stderr.puts *err.backtrace if $DEBUG
208
+ fail
209
+ end
210
+
211
+ conn = PGconn.connect( @conninfo )
212
+ conn.set_notice_processor do |message|
213
+ $stderr.puts( message ) if $DEBUG
214
+ end
215
+
216
+ return conn
217
+ end
218
+
219
+
220
+ def teardown_testing_db( conn )
221
+ puts "Tearing down test database"
222
+ conn.finish if conn
223
+ log_and_run @logfile, 'pg_ctl', '-D', @test_pgdata.to_s, 'stop'
224
+ end
225
+ end
226
+
227
+
@@ -0,0 +1,28 @@
1
+ require 'helper'
2
+ require 'adapter/postgres'
3
+
4
+ describe "Postgres adapter" do
5
+ include PgTestingHelper
6
+
7
+ before(:all) do
8
+ @conn = setup_testing_db( "adapterpsql" )
9
+
10
+ # add HSTORE compatibility
11
+ File.open(File.join(File.dirname(__FILE__),'..','examples','hstore.sql'),'r'){|f| @conn.exec(f.read)}
12
+
13
+ # this creates the table we want
14
+ @conn.exec("CREATE TABLE generic_hstore_table (data hstore)")
15
+ @conn.exec("INSERT INTO generic_hstore_table VALUES (''::hstore)")
16
+
17
+ @adapter = Adapter[:postgres].new(@conn)
18
+ end
19
+
20
+ before(:each) do
21
+ @adapter.clear
22
+ end
23
+
24
+ let(:adapter) { @adapter }
25
+ let(:client) { @conn }
26
+
27
+ it_should_behave_like 'a marshaled adapter'
28
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adapter-postgres
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - CLR
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-05-18 00:00:00.000000000 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: adapter-postgres
17
+ requirement: &15664160 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *15664160
26
+ - !ruby/object:Gem::Dependency
27
+ name: jeweler
28
+ requirement: &15663680 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *15663680
37
+ - !ruby/object:Gem::Dependency
38
+ name: yajl-ruby
39
+ requirement: &15663200 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *15663200
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &15662720 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '2.3'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *15662720
59
+ - !ruby/object:Gem::Dependency
60
+ name: log_buddy
61
+ requirement: &15662240 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 0.5.0
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *15662240
70
+ - !ruby/object:Gem::Dependency
71
+ name: timecop
72
+ requirement: &15661760 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.3.5
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *15661760
81
+ - !ruby/object:Gem::Dependency
82
+ name: i18n
83
+ requirement: &15661280 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - =
87
+ - !ruby/object:Gem::Version
88
+ version: 0.5.0
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *15661280
92
+ description: Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter
93
+ for more info.
94
+ email: clr@port49.com
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files:
98
+ - LICENSE
99
+ - README.rdoc
100
+ files:
101
+ - .document
102
+ - Gemfile
103
+ - Gemfile.lock
104
+ - LICENSE
105
+ - README.rdoc
106
+ - Rakefile
107
+ - VERSION
108
+ - adapter-postgres.gemspec
109
+ - examples/hstore.sql
110
+ - examples/postgres.rb
111
+ - lib/adapter-postgres.rb
112
+ - lib/adapter/postgres.rb
113
+ - lib/adapter/postgres/version.rb
114
+ - spec/helper.rb
115
+ - spec/pg_testing_helper.rb
116
+ - spec/postgres_spec.rb
117
+ has_rdoc: true
118
+ homepage: http://github.com/clr/adapter-postgres
119
+ licenses:
120
+ - MIT
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ segments:
132
+ - 0
133
+ hash: 3737740832435918876
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 1.6.2
143
+ signing_key:
144
+ specification_version: 3
145
+ summary: Postgres adapter for adapter gem. Uses the HSTORE data type. See adapter
146
+ for more info.
147
+ test_files: []