httpsql 0.0.1 → 0.1.0
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/README.md +87 -4
- data/Rakefile +7 -0
- data/httpsql.gemspec +8 -6
- data/lib/httpsql.rb +37 -32
- data/lib/httpsql/version.rb +1 -1
- data/test/httpsql_test.rb +126 -0
- metadata +64 -18
- checksums.yaml +0 -7
data/README.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# Httpsql
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Httpsql is a module, designed to be included in [Active Record](http://api.rubyonrails.org/classes/ActiveRecord/Base.html)
|
|
4
|
+
models exposed by [grape](https://github.com/intridea/grape). Once the module is
|
|
5
|
+
included, a given model can respond directly to query params passed to it, using
|
|
6
|
+
`where_params_eq`. You can also constrain the fields returned by the model,
|
|
7
|
+
using the `fields` query parameter.
|
|
8
|
+
|
|
9
|
+
Httpsql uses [ARel](http://www.slideshare.net/flah00/activerecord-arel) to
|
|
10
|
+
generate queries and exposes ARel's methods via query params. The supported ARel
|
|
11
|
+
methods are eq, not_eq, matches, does_not_match, gt, gteq, lt, lteq.
|
|
12
|
+
|
|
13
|
+
Httpsql also generates documentaion for endpoints, which can be easily merged
|
|
14
|
+
into your existing documentation (`#route_params`).
|
|
15
|
+
|
|
16
|
+
Httpsql reserves one parameter, access_token. If your model has a field called
|
|
17
|
+
access_token, you'll need to rename it.
|
|
4
18
|
|
|
5
19
|
## Installation
|
|
6
20
|
|
|
@@ -18,12 +32,81 @@ Or install it yourself as:
|
|
|
18
32
|
|
|
19
33
|
## Usage
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
Assume you have a model, widget, whose fields are id, int_field, string_field, created_at, updated_at.
|
|
36
|
+
|
|
37
|
+
create_table "widgets", :force => true do |t|
|
|
38
|
+
t.integer "int_field"
|
|
39
|
+
t.string "string_field"
|
|
40
|
+
t.datetime "created_at", :null => false
|
|
41
|
+
t.datetime "updated_at", :null => false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
### model.rb
|
|
45
|
+
|
|
46
|
+
class Widget < ActiveRecord::Base
|
|
47
|
+
include Httpsql
|
|
48
|
+
attr_accessible :int_field, :string_field
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
### api.rb
|
|
52
|
+
|
|
53
|
+
class Api < Grape::API
|
|
54
|
+
version 'v1'
|
|
55
|
+
logger Rails.logger
|
|
56
|
+
default_format :json
|
|
57
|
+
|
|
58
|
+
resource :widgets do
|
|
59
|
+
desc 'Get all widgets', {
|
|
60
|
+
optional_params: Widget.route_params
|
|
61
|
+
}
|
|
62
|
+
get '/' do
|
|
63
|
+
present Widget.where_params_eq(params)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
### config.ru
|
|
69
|
+
|
|
70
|
+
api = Rack::Builder.new do
|
|
71
|
+
run Api
|
|
72
|
+
end
|
|
73
|
+
run Rack::URLMap.new \
|
|
74
|
+
'/' => YourApp::Application,
|
|
75
|
+
'/api' => api
|
|
76
|
+
|
|
77
|
+
Now you're able to run your app
|
|
78
|
+
|
|
79
|
+
rails s
|
|
80
|
+
|
|
81
|
+
Query your new API
|
|
82
|
+
|
|
83
|
+
curl 'http://localhost:3000/api/v1/widgets'
|
|
84
|
+
SELECT * FROM widgets
|
|
85
|
+
|
|
86
|
+
curl 'http://localhost:3000/api/v1/widgets?id=1'
|
|
87
|
+
SELECT * FROM widgets WHERE id = 1
|
|
88
|
+
|
|
89
|
+
curl 'http://localhost:3000/api/v1/widgets?id[]=1&id[]=2'
|
|
90
|
+
SELECT * FROM widgets WHERE id IN (1,2)
|
|
91
|
+
|
|
92
|
+
curl 'http://localhost:3000/api/v1/widgets?id.gt=10&id.lt=100'
|
|
93
|
+
SELECT * FROM widgets WHERE id > 10 AND id < 100
|
|
94
|
+
|
|
95
|
+
curl 'http://localhost:3000/api/v1/widgets?id[]=1&id[]=2&created_at.gt=2013-06-01'
|
|
96
|
+
SELECT * FROM widgets WHERE id IN (1,2) AND created_at > '2013-06-01'
|
|
97
|
+
|
|
98
|
+
curl 'http://localhost:3000/api/v1/widgets?id[]=1&id[]=2&created_at.gt=2013-06-01&fields[]=id&fields[]=int_field'
|
|
99
|
+
SELECT id, int_field FROM widgets WHERE id IN (1,2) AND created_at > '2013-06-01'
|
|
100
|
+
|
|
101
|
+
curl 'http://localhost:3000/api/v1/describe_api'
|
|
102
|
+
Returns JSON describing the API
|
|
22
103
|
|
|
23
104
|
## Contributing
|
|
24
105
|
|
|
25
106
|
1. Fork it
|
|
26
107
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
27
108
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
28
|
-
|
|
29
|
-
|
|
109
|
+
* write some god damned tests
|
|
110
|
+
4. Run your god damned tests (`rake test`)
|
|
111
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
112
|
+
6. Create new Pull Request
|
data/Rakefile
CHANGED
data/httpsql.gemspec
CHANGED
|
@@ -6,11 +6,11 @@ require 'httpsql/version'
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "httpsql"
|
|
8
8
|
spec.version = Httpsql::VERSION
|
|
9
|
-
spec.authors = ["
|
|
10
|
-
spec.email = ["
|
|
11
|
-
spec.description = %q{
|
|
12
|
-
spec.summary = %q{
|
|
13
|
-
spec.homepage = ""
|
|
9
|
+
spec.authors = [ "Philip Champon", "Alejandro Ciniglio", "Sean Shillo" ]
|
|
10
|
+
spec.email = [ "philip@adaptly.com", "alejandro@adaptly.com", "sean@adaptly.com" ]
|
|
11
|
+
spec.description = %q{Expose model columns and ARel methods through query parameters in grape end points}
|
|
12
|
+
spec.summary = %q{Select model specified fields, create arbitrary queries, all using CGI query parameters}
|
|
13
|
+
spec.homepage = "https://github.com/Adaptly/httpsql"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
|
@@ -20,5 +20,7 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
22
|
spec.add_development_dependency "rake"
|
|
23
|
-
spec.add_dependency "
|
|
23
|
+
spec.add_dependency "activerecord", ">= 3.0"
|
|
24
|
+
spec.add_dependency "grape"
|
|
25
|
+
spec.add_development_dependency "sqlite3"
|
|
24
26
|
end
|
data/lib/httpsql.rb
CHANGED
|
@@ -1,42 +1,47 @@
|
|
|
1
1
|
require "httpsql/version"
|
|
2
2
|
|
|
3
3
|
module Httpsql
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def valid_params(params)
|
|
8
|
-
params.select{|k,v| column_names.include?(k.to_s.split('.').first)}
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def where_params_eq(params={})
|
|
12
|
-
|
|
13
|
-
cond = valid_params(params).map do |k,v|
|
|
14
|
-
next if k.to_s == 'access_token'
|
|
15
|
-
(k, m) = k.to_s.split('.')
|
|
16
|
-
if m
|
|
17
|
-
arel_table[k.to_sym].send(m.to_sym, v)
|
|
18
|
-
elsif v.respond_to?(:any?)
|
|
19
|
-
arel_table[k.to_sym].in(v)
|
|
20
|
-
else
|
|
21
|
-
arel_table[k.to_sym].eq(v)
|
|
22
|
-
end
|
|
23
|
-
end.inject{|x,y| x.and(y)}
|
|
24
|
-
|
|
25
|
-
where(cond)
|
|
26
|
-
end
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.send :extend, ClassMethods
|
|
6
|
+
end
|
|
27
7
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
8
|
+
module ClassMethods
|
|
9
|
+
def where_params_eq(params={})
|
|
10
|
+
cond = valid_params(params).map do |k,v|
|
|
11
|
+
(k, m) = k.to_s.split('.')
|
|
12
|
+
next if k.to_s == 'access_token'
|
|
13
|
+
if m
|
|
14
|
+
arel_table[k.to_sym].send(m.to_sym, v)
|
|
15
|
+
elsif v.respond_to?(:any?)
|
|
16
|
+
arel_table[k.to_sym].in(v)
|
|
17
|
+
else
|
|
18
|
+
arel_table[k.to_sym].eq(v)
|
|
36
19
|
end
|
|
37
|
-
end
|
|
20
|
+
end.inject{|x,y| x.and(y)}
|
|
38
21
|
|
|
22
|
+
ar_rel = where(cond)
|
|
23
|
+
ar_rel = ar_rel.select(params[:field]) if params[:field]
|
|
24
|
+
ar_rel
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def route_params
|
|
28
|
+
columns.inject({}) do |m,c|
|
|
29
|
+
m[c.name] = {
|
|
30
|
+
type: c.sql_type,
|
|
31
|
+
desc: c.name,
|
|
32
|
+
primary: c.primary
|
|
33
|
+
}
|
|
34
|
+
m
|
|
35
|
+
end.merge "field" => {
|
|
36
|
+
type: 'array',
|
|
37
|
+
desc: 'select fields',
|
|
38
|
+
primary: false
|
|
39
|
+
}
|
|
40
|
+
end
|
|
39
41
|
|
|
42
|
+
private
|
|
43
|
+
def valid_params(params)
|
|
44
|
+
params.select{|k,v| column_names.include?(k.to_s.split('.').first)}
|
|
40
45
|
end
|
|
41
46
|
end
|
|
42
47
|
end
|
data/lib/httpsql/version.rb
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'minitest/spec'
|
|
2
|
+
require 'minitest/autorun'
|
|
3
|
+
require 'active_record'
|
|
4
|
+
require 'httpsql'
|
|
5
|
+
|
|
6
|
+
ActiveRecord::Base.configurations[:test] = {adapter: 'sqlite3', database: 'tmp/httpsql_test'}
|
|
7
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[:test])
|
|
8
|
+
ActiveRecord::Base.connection.execute %Q{ DROP TABLE IF EXISTS foo_models }
|
|
9
|
+
ActiveRecord::Base.connection.execute %Q{
|
|
10
|
+
CREATE TABLE foo_models (
|
|
11
|
+
id integer,
|
|
12
|
+
int_field integer,
|
|
13
|
+
string_field text,
|
|
14
|
+
access_token text,
|
|
15
|
+
created_at text default CURRENT_TIMESTAMP,
|
|
16
|
+
updated_at text default CURRENT_TIMESTAMP,
|
|
17
|
+
primary key(id)
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
class FooModel < ActiveRecord::Base
|
|
21
|
+
include Httpsql
|
|
22
|
+
attr_accessible :int_field, :string_field, :access_token
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def generate_models
|
|
26
|
+
FooModel.create!([
|
|
27
|
+
{int_field: 0, string_field: "zero", access_token: "000"},
|
|
28
|
+
{int_field: 1, string_field: "one", access_token: "111"},
|
|
29
|
+
{int_field: 2, string_field: "two", access_token: "222"},
|
|
30
|
+
{int_field: 3, string_field: "three", access_token: "333"},
|
|
31
|
+
{int_field: 4, string_field: "four", access_token: "444"},
|
|
32
|
+
])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe Httpsql do
|
|
36
|
+
before :each do
|
|
37
|
+
FooModel.connection.execute %Q{DELETE FROM foo_models}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'selects a model\'s columns from a given hash' do
|
|
41
|
+
ret = FooModel.send(:valid_params, id: 1, int_field: 2, string_field: "foo", access_token: "a", created_at: '2013-01-01T00:00:00', created_at: '2013-01-01T00:00:00', foo: :bar)
|
|
42
|
+
ret.must_equal(id: 1, int_field: 2, string_field: "foo", access_token: "a", created_at: '2013-01-01T00:00:00', created_at: '2013-01-01T00:00:00')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'selects all models' do
|
|
46
|
+
models = generate_models
|
|
47
|
+
FooModel.where_params_eq({}).must_equal models
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'selects a specified array of models' do
|
|
51
|
+
models = generate_models
|
|
52
|
+
FooModel.where_params_eq("int_field" => [0, 1]).must_equal models[0..1]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'selects a model, using eq' do
|
|
56
|
+
models = generate_models
|
|
57
|
+
FooModel.where_params_eq("int_field.eq" => 0).must_equal [models[0]]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'selects models, using not_eq' do
|
|
61
|
+
models = generate_models
|
|
62
|
+
FooModel.where_params_eq("int_field.not_eq" => 0).must_equal models[1..-1]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'selects a model, using matches' do
|
|
66
|
+
models = generate_models
|
|
67
|
+
FooModel.where_params_eq("string_field.matches" => "%hre%").must_equal [models[3]]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'selects models, using does_not_match' do
|
|
71
|
+
models = generate_models
|
|
72
|
+
FooModel.where_params_eq("string_field.does_not_match" => "%ero").must_equal models[1..-1]
|
|
73
|
+
end
|
|
74
|
+
it 'selects models, using gt' do
|
|
75
|
+
models = generate_models
|
|
76
|
+
FooModel.where_params_eq("int_field.gt" => 1).must_equal models[2..-1]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'selects models, using gteq' do
|
|
80
|
+
models = generate_models
|
|
81
|
+
FooModel.where_params_eq("int_field.gteq" => 2).must_equal models[2..-1]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'select models, using lt' do
|
|
85
|
+
models = generate_models
|
|
86
|
+
FooModel.where_params_eq("int_field.lt" => 1).must_equal [models[0]]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'selects models, using lteq' do
|
|
90
|
+
models = generate_models
|
|
91
|
+
FooModel.where_params_eq("int_field.lteq" => 2).must_equal models[0..2]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'selects models, using two ARel methods' do
|
|
95
|
+
models = generate_models
|
|
96
|
+
FooModel.where_params_eq("int_field.gteq" => 1, "id.gt" => 4).must_equal [models[4]]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'ignores access_token' do
|
|
100
|
+
models = generate_models
|
|
101
|
+
FooModel.where_params_eq("access_token" => "111").must_equal models
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'ignores access_token dot notation' do
|
|
105
|
+
models = generate_models
|
|
106
|
+
FooModel.where_params_eq("access_token.eq" => "111").must_equal models
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'selects a model with specified fields' do
|
|
110
|
+
generate_models
|
|
111
|
+
model = FooModel.select([:int_field, :id]).where(int_field: 0)
|
|
112
|
+
FooModel.where_params_eq("int_field.eq" => 0, field: [:int_field, :id]).must_equal model
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it 'generates the correct documentation' do
|
|
116
|
+
FooModel.route_params.must_equal({
|
|
117
|
+
"id" => {:type => "integer", :desc => "id", :primary => true},
|
|
118
|
+
"int_field" => {:type => "integer", :desc => "int_field", :primary => false},
|
|
119
|
+
"string_field" => {:type => "text", :desc => "string_field", :primary => false},
|
|
120
|
+
"access_token" => {:type => "text", :desc => "access_token", :primary => false},
|
|
121
|
+
"created_at" => {:type => "text", :desc => "created_at", :primary => false},
|
|
122
|
+
"updated_at" => {:type => "text", :desc => "updated_at", :primary => false},
|
|
123
|
+
"field" => {:type => "array", :desc => "select fields", :primary => false}}
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
end
|
metadata
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: httpsql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
prerelease:
|
|
5
6
|
platform: ruby
|
|
6
7
|
authors:
|
|
7
|
-
-
|
|
8
|
+
- Philip Champon
|
|
8
9
|
- Alejandro Ciniglio
|
|
10
|
+
- Sean Shillo
|
|
9
11
|
autorequire:
|
|
10
12
|
bindir: bin
|
|
11
13
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
14
|
+
date: 2013-07-03 00:00:00.000000000 Z
|
|
13
15
|
dependencies:
|
|
14
16
|
- !ruby/object:Gem::Dependency
|
|
15
17
|
name: bundler
|
|
16
18
|
requirement: !ruby/object:Gem::Requirement
|
|
19
|
+
none: false
|
|
17
20
|
requirements:
|
|
18
21
|
- - ~>
|
|
19
22
|
- !ruby/object:Gem::Version
|
|
@@ -21,6 +24,7 @@ dependencies:
|
|
|
21
24
|
type: :development
|
|
22
25
|
prerelease: false
|
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
|
27
|
+
none: false
|
|
24
28
|
requirements:
|
|
25
29
|
- - ~>
|
|
26
30
|
- !ruby/object:Gem::Version
|
|
@@ -28,35 +32,73 @@ dependencies:
|
|
|
28
32
|
- !ruby/object:Gem::Dependency
|
|
29
33
|
name: rake
|
|
30
34
|
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
none: false
|
|
31
36
|
requirements:
|
|
32
|
-
- - '>='
|
|
37
|
+
- - ! '>='
|
|
33
38
|
- !ruby/object:Gem::Version
|
|
34
39
|
version: '0'
|
|
35
40
|
type: :development
|
|
36
41
|
prerelease: false
|
|
37
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
none: false
|
|
38
44
|
requirements:
|
|
39
|
-
- - '>='
|
|
45
|
+
- - ! '>='
|
|
40
46
|
- !ruby/object:Gem::Version
|
|
41
47
|
version: '0'
|
|
42
48
|
- !ruby/object:Gem::Dependency
|
|
43
|
-
name:
|
|
49
|
+
name: activerecord
|
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
|
51
|
+
none: false
|
|
52
|
+
requirements:
|
|
53
|
+
- - ! '>='
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '3.0'
|
|
56
|
+
type: :runtime
|
|
57
|
+
prerelease: false
|
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
59
|
+
none: false
|
|
60
|
+
requirements:
|
|
61
|
+
- - ! '>='
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '3.0'
|
|
64
|
+
- !ruby/object:Gem::Dependency
|
|
65
|
+
name: grape
|
|
44
66
|
requirement: !ruby/object:Gem::Requirement
|
|
67
|
+
none: false
|
|
45
68
|
requirements:
|
|
46
|
-
- - '>='
|
|
69
|
+
- - ! '>='
|
|
47
70
|
- !ruby/object:Gem::Version
|
|
48
71
|
version: '0'
|
|
49
72
|
type: :runtime
|
|
50
73
|
prerelease: false
|
|
51
74
|
version_requirements: !ruby/object:Gem::Requirement
|
|
75
|
+
none: false
|
|
76
|
+
requirements:
|
|
77
|
+
- - ! '>='
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: sqlite3
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
none: false
|
|
84
|
+
requirements:
|
|
85
|
+
- - ! '>='
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
type: :development
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
91
|
+
none: false
|
|
52
92
|
requirements:
|
|
53
|
-
- - '>='
|
|
93
|
+
- - ! '>='
|
|
54
94
|
- !ruby/object:Gem::Version
|
|
55
95
|
version: '0'
|
|
56
|
-
description:
|
|
96
|
+
description: Expose model columns and ARel methods through query parameters in grape
|
|
97
|
+
end points
|
|
57
98
|
email:
|
|
58
|
-
-
|
|
99
|
+
- philip@adaptly.com
|
|
59
100
|
- alejandro@adaptly.com
|
|
101
|
+
- sean@adaptly.com
|
|
60
102
|
executables: []
|
|
61
103
|
extensions: []
|
|
62
104
|
extra_rdoc_files: []
|
|
@@ -69,28 +111,32 @@ files:
|
|
|
69
111
|
- httpsql.gemspec
|
|
70
112
|
- lib/httpsql.rb
|
|
71
113
|
- lib/httpsql/version.rb
|
|
72
|
-
|
|
114
|
+
- test/httpsql_test.rb
|
|
115
|
+
homepage: https://github.com/Adaptly/httpsql
|
|
73
116
|
licenses:
|
|
74
117
|
- MIT
|
|
75
|
-
metadata: {}
|
|
76
118
|
post_install_message:
|
|
77
119
|
rdoc_options: []
|
|
78
120
|
require_paths:
|
|
79
121
|
- lib
|
|
80
122
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
|
+
none: false
|
|
81
124
|
requirements:
|
|
82
|
-
- - '>='
|
|
125
|
+
- - ! '>='
|
|
83
126
|
- !ruby/object:Gem::Version
|
|
84
127
|
version: '0'
|
|
85
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
|
+
none: false
|
|
86
130
|
requirements:
|
|
87
|
-
- - '>='
|
|
131
|
+
- - ! '>='
|
|
88
132
|
- !ruby/object:Gem::Version
|
|
89
133
|
version: '0'
|
|
90
134
|
requirements: []
|
|
91
135
|
rubyforge_project:
|
|
92
|
-
rubygems_version:
|
|
136
|
+
rubygems_version: 1.8.23
|
|
93
137
|
signing_key:
|
|
94
|
-
specification_version:
|
|
95
|
-
summary:
|
|
96
|
-
|
|
138
|
+
specification_version: 3
|
|
139
|
+
summary: Select model specified fields, create arbitrary queries, all using CGI query
|
|
140
|
+
parameters
|
|
141
|
+
test_files:
|
|
142
|
+
- test/httpsql_test.rb
|
checksums.yaml
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
SHA1:
|
|
3
|
-
metadata.gz: 9fd889994ae94496fde8767ceb1aeedb6bf7b580
|
|
4
|
-
data.tar.gz: 9d54f043cfac281572b16ba80d02379d142824a4
|
|
5
|
-
SHA512:
|
|
6
|
-
metadata.gz: 47fd7364530a7db44688280d83c3c8f23a5f72379b9b2948abf3beb1a9f6f87b21bff82cd5fc7757362886db53ce79150ddef029b360a1268d7a8358a6c7590c
|
|
7
|
-
data.tar.gz: b7ca268a828be986d6b1186c411af54af0e4bd4b1f997a563c0abb487b827168ef1d9387d8ddc2d9072d9be4b311eb2096951887c6233ee36d6eadd2f3aba8f7
|