adapter-postgres 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: []