postgrest 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/workflow.yml +35 -0
- data/.rubocop.yml +5 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +82 -28
- data/lib/postgrest.rb +19 -2
- data/lib/postgrest/builders/base_builder.rb +29 -0
- data/lib/postgrest/builders/filter_builder.rb +111 -0
- data/lib/postgrest/builders/query_builder.rb +48 -0
- data/lib/postgrest/client.rb +1 -1
- data/lib/postgrest/http.rb +64 -67
- data/lib/postgrest/responses/base_response.rb +55 -0
- data/lib/postgrest/responses/delete_response.rb +8 -0
- data/lib/postgrest/responses/get_response.rb +8 -0
- data/lib/postgrest/responses/patch_response.rb +8 -0
- data/lib/postgrest/responses/post_response.rb +8 -0
- data/lib/postgrest/version.rb +1 -1
- metadata +12 -5
- data/lib/postgrest/query_builder.rb +0 -27
- data/lib/postgrest/response.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 047e65fe75ff575aebb1d38597b1de103609c19daff24efc97ab0f3d8f162f11
|
4
|
+
data.tar.gz: fb1e60e8d2e299faec971a00e5dc86a1dbb816d925de5695f7e0cf7bc7b4b814
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d8e89bc085fdd6383608941e1b00d6a9aab78bbd677d7b9f8392417be71754148879a9260627865b829a096531ee2dbb6452df03b55b90a9480b953d1286e47
|
7
|
+
data.tar.gz: c43e1fd2180a7202f3c59acf224d0ff5dd190feebe23cb05efc02e5d6690329511c44e1ac984a6c2382cdcca58086097b56307c55d95a03b2616c54001bdaa39
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
23
|
+
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- name: Set up Ruby
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
+
# uses: ruby/setup-ruby@v1
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rake
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
inherit_mode:
|
2
|
+
merge:
|
3
|
+
- Exclude
|
1
4
|
AllCops:
|
2
5
|
SuggestExtensions: false
|
3
6
|
Exclude:
|
@@ -5,9 +8,7 @@ AllCops:
|
|
5
8
|
- 'bin/**/*'
|
6
9
|
Style/Documentation:
|
7
10
|
Enabled: false
|
8
|
-
Style/
|
11
|
+
Style/MissingRespondToMissing:
|
9
12
|
Enabled: false
|
10
|
-
|
13
|
+
Naming/MethodParameterName:
|
11
14
|
Enabled: false
|
12
|
-
Lint/UriEscapeUnescape:
|
13
|
-
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
## Status
|
4
4
|
|
5
5
|
[![Build Status](https://api.travis-ci.com/marcelobarreto/postgrest-rb.svg?branch=master)](https://travis-ci.com/marcelobarreto/postgrest-rb)
|
6
|
-
[![Code Climate](https://codeclimate.com/github/marcelobarreto/postgrest-rb.svg)](https://codeclimate.com/github/
|
6
|
+
[![Code Climate](https://codeclimate.com/github/marcelobarreto/postgrest-rb.svg)](https://codeclimate.com/github/marcelobarreto/postgrest-rb)
|
7
7
|
[![Code Climate](https://codeclimate.com/github/marcelobarreto/postgrest-rb/coverage.svg)](https://codeclimate.com/github/marcelobarreto/postgrest-rb)
|
8
8
|
[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
|
9
|
-
[![RubyGems](
|
9
|
+
[![RubyGems](https://img.shields.io/gem/dt/postgrest.svg?style=flat)](https://rubygems.org/gems/postgrest)
|
10
10
|
|
11
11
|
Ruby client for [PostgREST](https://postgrest.org/)
|
12
12
|
|
@@ -41,51 +41,105 @@ db = Postgrest::Client.new(url: url, headers: headers, schema: schema)
|
|
41
41
|
```ruby
|
42
42
|
# Basic select
|
43
43
|
|
44
|
-
db.from('todos').select('*')
|
44
|
+
db.from('todos').select('*').execute
|
45
|
+
# or just db.from('todos').select
|
45
46
|
|
46
|
-
|
47
|
-
@body={:select=>"*"},
|
48
|
-
@count=1,
|
49
|
-
@data=[{"id"=>1, "title"=>"Go to the gym", "completed"=>false}],
|
50
|
-
@error=true,
|
51
|
-
@status=200,
|
52
|
-
@status_text="OK">
|
47
|
+
#<Postgrest::Responses::GetResponse GET OK data=[{"id"=>1, "title"=>"foo", "completed"=>false}, {"id"=>2, "title"=>"foo", "completed"=>false}]>
|
53
48
|
|
54
49
|
# Selecting just one or more fields
|
50
|
+
db.from('todos').select(:title).execute
|
55
51
|
|
56
|
-
|
52
|
+
#<Postgrest::Responses::GetResponse GET OK data=[{"title"=>"foo"}, {"title"=>"foo"}]>
|
53
|
+
|
54
|
+
```
|
55
|
+
|
56
|
+
#### Renaming a column name
|
57
|
+
|
58
|
+
You have the ability to alias the name of the column you want doing as follows:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
db.from('todos').select('name:title').eq(id: 112).execute
|
62
|
+
#<Postgrest::Responses::GetResponse GET OK data=[{"name"=>"Go to the gym"}]>
|
63
|
+
```
|
64
|
+
|
65
|
+
### Querying
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
db.from('todos').select('*').eq(id: 100).execute
|
69
|
+
#<Postgrest::Responses::GetResponse GET OK data=[{"id" => 100, "title"=>"foo", "completed" => true}}]>
|
57
70
|
|
58
|
-
<Postgrest::Response:0x0000556745590770
|
59
|
-
@body={:select=>"title, completed"},
|
60
|
-
@count=1,
|
61
|
-
@data=[{"title"=>"Go to the gym", "completed"=>false}],
|
62
|
-
@error=true,
|
63
|
-
@status=200,
|
64
|
-
@status_text="OK">
|
65
71
|
|
72
|
+
db.from('todos').select('*').neq(id: 100).execute
|
73
|
+
#<Postgrest::Responses::GetResponse GET OK data=[{"id" => 101, "title"=>"foo", "completed" => true}}]>
|
74
|
+
```
|
75
|
+
|
76
|
+
### Ordering
|
77
|
+
|
78
|
+
TODO
|
79
|
+
|
80
|
+
### Relationships
|
81
|
+
|
82
|
+
TODO
|
83
|
+
|
84
|
+
### Full query example
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
db.from('todos').select(:id, :title).owners(:name, as: :owner).workers(:name, as: :worker).in(id: [112, 113]).order(id: :asc).execute
|
88
|
+
|
89
|
+
#<Postgrest::Responses::GetResponse GET OK data=[{"id"=>112, "title"=>"Eat something", "owner"=>{"name"=>"Marcelo"}, "worker"=>{"name"=>"Marcelo"}}, {"id"=>113, "title"=>"Go to the gym", "owner"=>{"name"=>"Marcelo"}, "worker"=>nil}]>
|
66
90
|
```
|
67
91
|
|
68
92
|
### Inserting
|
69
93
|
|
70
94
|
```ruby
|
71
|
-
db.from('todos').insert(
|
95
|
+
db.from('todos').insert(title: 'Go to the gym', completed: false).execute
|
96
|
+
|
97
|
+
#<Postgrest::Responses::PostResponse POST Created data=[{"id"=>1, "title"=>"Go to the gym", "completed"=>false}]>
|
72
98
|
|
73
|
-
|
99
|
+
db.from('todos').upsert(id: 1, title: 'Ok, I wont go to the gym', completed: true).execute
|
100
|
+
|
101
|
+
#<Postgrest::Responses::PostResponse POST Created data=[{"id"=>1, "title"=>"Ok, I wont go to the gym", "completed"=>true}]>
|
74
102
|
|
75
103
|
# Inserting multiple rows at once
|
76
104
|
db.from('todos').insert([
|
77
105
|
{ title: 'Go to the gym', completed: false },
|
78
106
|
{ title: 'Walk in the park', completed: true },
|
79
|
-
])
|
107
|
+
]).execute
|
108
|
+
|
109
|
+
#<Postgrest::Responses::PostResponse POST Created data=[{"id"=>110, "title"=>"Go to the gym", "completed"=>false}, {"id"=>111, "title"=>"Walk in the park", "completed"=>true}]>
|
110
|
+
|
111
|
+
```
|
112
|
+
|
113
|
+
### Updating
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
|
117
|
+
# Query before update
|
118
|
+
|
119
|
+
db.from('todos').update(title: 'foobar').eq(id: 109).execute
|
120
|
+
|
121
|
+
#<Postgrest::Responses::PatchResponse PATCH OK data=[{"id"=>106, "title"=>"foo", "completed"=>false}]>
|
122
|
+
|
123
|
+
# Update all rows
|
124
|
+
|
125
|
+
db.from('todos').update(title: 'foobar').execute
|
126
|
+
|
127
|
+
#<Postgrest::Responses::PatchResponse PATCH OK data=[{"id"=>107, "title"=>"foobar", "completed"=>false}, {"id"=>1, "title"=>"foobar", "completed"=>true}, {"id"=>110, "title"=>"foobar", "completed"=>false}, {"id"=>111, "title"=>"foobar", "completed"=>true}, {"id"=>106, "title"=>"foobar", "completed"=>false}]>
|
128
|
+
```
|
129
|
+
|
130
|
+
### Deleting
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
# Querying before delete
|
134
|
+
|
135
|
+
db.from('todos').delete.eq(id: 109).execute
|
136
|
+
#<Postgrest::Responses::DeleteResponse DELETE OK data=[{"id"=>109, "title"=>"Go to the gym", "completed"=>false}]>
|
137
|
+
|
138
|
+
# OR deleting everything
|
80
139
|
|
81
|
-
|
82
|
-
@body=[{:title=>"Go to the gym", :completed=>false}, {:title=>"Walk in the park", :completed=>true}],
|
83
|
-
@count=nil,
|
84
|
-
@data="",
|
85
|
-
@error=true,
|
86
|
-
@status=201,
|
87
|
-
@status_text="Created">
|
140
|
+
db.from('todos').delete.execute
|
88
141
|
|
142
|
+
#<Postgrest::Responses::DeleteResponse DELETE OK data=[{"id"=>110, "title"=>"Go to the gym", "completed"=>false}, {"id"=>111, "title"=>"Go to the gym", "completed"=>false}]>
|
89
143
|
```
|
90
144
|
|
91
145
|
## Development
|
data/lib/postgrest.rb
CHANGED
@@ -1,13 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'cgi'
|
6
|
+
|
3
7
|
require 'postgrest/version'
|
8
|
+
|
9
|
+
# Builders
|
10
|
+
require 'postgrest/builders/base_builder'
|
11
|
+
require 'postgrest/builders/query_builder'
|
12
|
+
require 'postgrest/builders/filter_builder'
|
13
|
+
|
14
|
+
# Responses
|
15
|
+
require 'postgrest/responses/base_response'
|
16
|
+
require 'postgrest/responses/get_response'
|
17
|
+
require 'postgrest/responses/post_response'
|
18
|
+
require 'postgrest/responses/patch_response'
|
19
|
+
require 'postgrest/responses/delete_response'
|
20
|
+
|
4
21
|
require 'postgrest/http'
|
5
22
|
require 'postgrest/client'
|
6
|
-
require 'postgrest/query_builder'
|
7
|
-
require 'postgrest/response'
|
8
23
|
|
9
24
|
module Postgrest
|
10
25
|
class MissingTableError < StandardError; end
|
11
26
|
|
27
|
+
class InvalidHTTPMethod < ArgumentError; end
|
28
|
+
|
12
29
|
class RequestError < StandardError; end
|
13
30
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Postgrest
|
4
|
+
module Builders
|
5
|
+
class BaseBuilder
|
6
|
+
def self.before_execute_hooks
|
7
|
+
@before_execute ||= []
|
8
|
+
@before_execute
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.before_execute(*values)
|
12
|
+
@before_execute = values
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :http
|
16
|
+
|
17
|
+
def initialize(http)
|
18
|
+
@http = http
|
19
|
+
end
|
20
|
+
|
21
|
+
def call
|
22
|
+
self.class.before_execute_hooks.each { |method_name| send(method_name) }
|
23
|
+
|
24
|
+
http.call
|
25
|
+
end
|
26
|
+
alias execute call
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Postgrest
|
4
|
+
module Builders
|
5
|
+
class FilterBuilder < BaseBuilder
|
6
|
+
before_execute :set_limit, :set_offset, :update_http_instance
|
7
|
+
|
8
|
+
SIMPLE_MATCHERS = %i[eq neq gt gte lt lte like is ilike fts plfts phfts wfts].freeze
|
9
|
+
RANGE_MATCHERS = %i[sl sr nxr nxl adj].freeze
|
10
|
+
|
11
|
+
def initialize(http)
|
12
|
+
super
|
13
|
+
@inverse_next = false
|
14
|
+
end
|
15
|
+
|
16
|
+
SIMPLE_MATCHERS.each do |method_name|
|
17
|
+
define_method(method_name) do |values|
|
18
|
+
transform_params(method_name: method_name, values: values)
|
19
|
+
|
20
|
+
self
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
RANGE_MATCHERS.each do |method_name|
|
25
|
+
define_method(method_name) do |values|
|
26
|
+
transform_params(method_name: method_name, values: values) do |key, value|
|
27
|
+
[key, "range=#{method_key(method_name)}.(#{value.join(',')})"]
|
28
|
+
end
|
29
|
+
|
30
|
+
self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def in(values = [])
|
35
|
+
transform_params(method_name: __method__, values: values) do |key, value|
|
36
|
+
[key, "#{method_key(__method__)}.(#{value.join(',')})"]
|
37
|
+
end
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def order(values)
|
43
|
+
transform_params(method_name: __method__, values: values) do |key, value|
|
44
|
+
asc = value.to_sym != :desc
|
45
|
+
asc = !asc if should_invert?
|
46
|
+
|
47
|
+
[__method__, "#{key}.#{asc ? 'asc' : 'desc'}"]
|
48
|
+
end
|
49
|
+
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_missing(method_name, *columns, as: nil)
|
54
|
+
decoded_query['select'] += as ? ",#{as}:#{method_name}" : ",#{method_name}"
|
55
|
+
decoded_query['select'] += columns.empty? ? '(*)' : "(#{columns.join(',')})"
|
56
|
+
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def query
|
61
|
+
http.uri.query
|
62
|
+
end
|
63
|
+
|
64
|
+
def decoded_query
|
65
|
+
@decoded_query ||= URI.decode_www_form(query).to_h
|
66
|
+
end
|
67
|
+
|
68
|
+
def limit(number = 0)
|
69
|
+
decoded_query['limit'] = number
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def offset(number = 0)
|
74
|
+
decoded_query['offset'] = number
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def not
|
79
|
+
@inverse_next = !@inverse_next
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def should_invert?
|
86
|
+
@inverse_next
|
87
|
+
end
|
88
|
+
|
89
|
+
def transform_params(values:, method_name:)
|
90
|
+
values.each do |k, v|
|
91
|
+
key, value = yield(k, v) if block_given?
|
92
|
+
key ||= k
|
93
|
+
value ||= "#{method_key(method_name)}.#{v}"
|
94
|
+
|
95
|
+
decoded_query[key.to_s] = value
|
96
|
+
end
|
97
|
+
|
98
|
+
@inverse_next = false
|
99
|
+
end
|
100
|
+
|
101
|
+
def method_key(name)
|
102
|
+
should_invert? ? "not.#{name}" : name
|
103
|
+
end
|
104
|
+
|
105
|
+
# Before execute callback
|
106
|
+
def update_http_instance
|
107
|
+
http.update_query_params(decoded_query)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Postgrest
|
4
|
+
module Builders
|
5
|
+
class QueryBuilder
|
6
|
+
attr_reader :uri, :headers, :schema
|
7
|
+
|
8
|
+
def initialize(url:, headers:, schema:)
|
9
|
+
@uri = URI(url)
|
10
|
+
@headers = headers
|
11
|
+
@schema = schema
|
12
|
+
end
|
13
|
+
|
14
|
+
def select(*columns, extra_headers: {})
|
15
|
+
columns.compact!
|
16
|
+
columns = ['*'] if columns.length.zero?
|
17
|
+
request = HTTP.new(uri: uri, query: { select: columns.join(',') }, headers: headers.merge(extra_headers))
|
18
|
+
|
19
|
+
FilterBuilder.new(request)
|
20
|
+
end
|
21
|
+
|
22
|
+
def insert(values)
|
23
|
+
upsert(values, extra_headers: { Prefer: 'return=representation' })
|
24
|
+
end
|
25
|
+
|
26
|
+
def upsert(values, extra_headers: {})
|
27
|
+
extra_headers[:Prefer] ||= 'return=representation,resolution=merge-duplicates'
|
28
|
+
request = HTTP.new(uri: uri, body: values, http_method: :post, headers: headers.merge(extra_headers))
|
29
|
+
|
30
|
+
BaseBuilder.new(request)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update(values, extra_headers: {})
|
34
|
+
extra_headers[:Prefer] ||= 'return=representation'
|
35
|
+
request = HTTP.new(uri: uri, body: values, http_method: :patch, headers: headers.merge(extra_headers))
|
36
|
+
|
37
|
+
FilterBuilder.new(request)
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(extra_headers: {})
|
41
|
+
extra_headers[:Prefer] ||= 'return=representation'
|
42
|
+
request = HTTP.new(uri: uri, http_method: :delete, headers: headers.merge(extra_headers))
|
43
|
+
|
44
|
+
FilterBuilder.new(request)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/postgrest/client.rb
CHANGED
@@ -15,7 +15,7 @@ module Postgrest
|
|
15
15
|
def from(table)
|
16
16
|
raise MissingTableError if table.nil? || table.empty?
|
17
17
|
|
18
|
-
|
18
|
+
Builders::QueryBuilder.new(url: "#{url}/#{table}", headers: headers, schema: schema)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/postgrest/http.rb
CHANGED
@@ -1,87 +1,84 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'net/http'
|
4
|
-
require 'json'
|
5
|
-
|
6
3
|
module Postgrest
|
7
4
|
class HTTP
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
5
|
+
METHODS = {
|
6
|
+
get: Net::HTTP::Get,
|
7
|
+
post: Net::HTTP::Post,
|
8
|
+
patch: Net::HTTP::Patch,
|
9
|
+
put: Net::HTTP::Patch,
|
10
|
+
delete: Net::HTTP::Delete
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
RESPONSES = {
|
14
|
+
get: Responses::GetResponse,
|
15
|
+
post: Responses::PostResponse,
|
16
|
+
put: Responses::PatchResponse,
|
17
|
+
patch: Responses::PatchResponse,
|
18
|
+
delete: Responses::DeleteResponse,
|
19
|
+
options: Responses::GetResponse # ?
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
USER_AGENT = 'PostgREST Ruby Client'
|
23
|
+
|
24
|
+
attr_reader :request, :response, :query, :body, :headers, :http_method, :uri
|
25
|
+
|
26
|
+
def initialize(uri:, query: {}, body: {}, headers: {}, http_method: :get)
|
27
|
+
@uri = uri
|
28
|
+
@body = body
|
29
|
+
@headers = headers
|
30
|
+
@http_method = http_method.to_sym
|
31
|
+
@response = nil
|
32
|
+
@request = nil
|
33
|
+
uri.query = decode_query_params(query)
|
34
|
+
end
|
21
35
|
|
22
|
-
|
23
|
-
|
36
|
+
def update_query_params(new_value = {})
|
37
|
+
@uri.query = decode_query_params(new_value)
|
38
|
+
rescue NoMethodError
|
39
|
+
@uri.query
|
40
|
+
end
|
24
41
|
|
25
|
-
|
26
|
-
|
27
|
-
uri.query = URI.encode_www_form(query)
|
28
|
-
req = Net::HTTP::Get.new(uri)
|
29
|
-
set_request_headers(req, headers)
|
30
|
-
http.request(req)
|
31
|
-
end
|
42
|
+
def call
|
43
|
+
raise InvalidHTTPMethod unless valid_http_method?
|
32
44
|
|
33
|
-
|
45
|
+
@response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl?) do |http|
|
46
|
+
@request = create_request
|
47
|
+
http.request(request)
|
34
48
|
end
|
35
49
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
req.body = body.to_json
|
40
|
-
req.content_type = 'application/json'
|
41
|
-
set_request_headers(req, headers)
|
42
|
-
http.request(req)
|
43
|
-
end
|
50
|
+
RESPONSES[http_method].new(request, response)
|
51
|
+
end
|
52
|
+
alias execute call
|
44
53
|
|
45
|
-
|
46
|
-
end
|
54
|
+
private
|
47
55
|
|
48
|
-
|
56
|
+
def decode_query_params(query_params)
|
57
|
+
CGI.unescape(URI.encode_www_form(query_params))
|
58
|
+
end
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
|
60
|
+
def create_request
|
61
|
+
request = METHODS[http_method].new(uri)
|
62
|
+
request.body = body.to_json
|
63
|
+
request.content_type = 'application/json'
|
64
|
+
add_headers(request)
|
53
65
|
|
54
|
-
|
55
|
-
|
66
|
+
request
|
67
|
+
end
|
56
68
|
|
57
|
-
|
69
|
+
def use_ssl?
|
70
|
+
uri.scheme == 'https'
|
71
|
+
end
|
58
72
|
|
59
|
-
|
60
|
-
|
73
|
+
def add_headers(request)
|
74
|
+
headers.each { |key, value| request[key] = value }
|
75
|
+
request['User-Agent'] = USER_AGENT
|
61
76
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
Response.new({
|
66
|
-
error: !response_is_successful?(response),
|
67
|
-
data: data,
|
68
|
-
count: data.count,
|
69
|
-
status: response.code.to_i,
|
70
|
-
status_text: response.message,
|
71
|
-
body: body
|
72
|
-
})
|
73
|
-
end
|
77
|
+
nil
|
78
|
+
end
|
74
79
|
|
75
|
-
|
76
|
-
|
77
|
-
error: !response_is_successful?(response),
|
78
|
-
data: parse_post_response(response),
|
79
|
-
count: nil,
|
80
|
-
status: response.code.to_i,
|
81
|
-
status_text: response.message,
|
82
|
-
body: body
|
83
|
-
})
|
84
|
-
end
|
80
|
+
def valid_http_method?
|
81
|
+
METHODS.keys.include?(http_method)
|
85
82
|
end
|
86
83
|
end
|
87
84
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Postgrest
|
4
|
+
module Responses
|
5
|
+
class BaseResponse
|
6
|
+
attr_reader :request, :response
|
7
|
+
|
8
|
+
def initialize(request, response)
|
9
|
+
@request = request
|
10
|
+
@response = response
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"\#<#{self.class} #{request.method} #{response.message} data=#{@data}>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def error
|
19
|
+
!response.is_a?(Net::HTTPSuccess)
|
20
|
+
end
|
21
|
+
|
22
|
+
def count
|
23
|
+
data.count
|
24
|
+
end
|
25
|
+
|
26
|
+
def status
|
27
|
+
response.code.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
def status_text
|
31
|
+
response.message
|
32
|
+
end
|
33
|
+
|
34
|
+
def data
|
35
|
+
error ? [] : safe_json_parse(response.body)
|
36
|
+
end
|
37
|
+
alias as_json data
|
38
|
+
|
39
|
+
def params
|
40
|
+
{
|
41
|
+
query: request.uri.query,
|
42
|
+
body: safe_json_parse(request.body)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def safe_json_parse(json)
|
49
|
+
JSON.parse(json)
|
50
|
+
rescue TypeError, JSON::ParserError
|
51
|
+
{}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/postgrest/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcelo Barreto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-05-
|
11
|
+
date: 2021-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -74,6 +74,7 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- ".codeclimate.yml"
|
77
|
+
- ".github/workflows/workflow.yml"
|
77
78
|
- ".gitignore"
|
78
79
|
- ".rspec"
|
79
80
|
- ".rubocop.yml"
|
@@ -86,10 +87,16 @@ files:
|
|
86
87
|
- bin/console
|
87
88
|
- bin/setup
|
88
89
|
- lib/postgrest.rb
|
90
|
+
- lib/postgrest/builders/base_builder.rb
|
91
|
+
- lib/postgrest/builders/filter_builder.rb
|
92
|
+
- lib/postgrest/builders/query_builder.rb
|
89
93
|
- lib/postgrest/client.rb
|
90
94
|
- lib/postgrest/http.rb
|
91
|
-
- lib/postgrest/
|
92
|
-
- lib/postgrest/
|
95
|
+
- lib/postgrest/responses/base_response.rb
|
96
|
+
- lib/postgrest/responses/delete_response.rb
|
97
|
+
- lib/postgrest/responses/get_response.rb
|
98
|
+
- lib/postgrest/responses/patch_response.rb
|
99
|
+
- lib/postgrest/responses/post_response.rb
|
93
100
|
- lib/postgrest/version.rb
|
94
101
|
- postgrest.gemspec
|
95
102
|
homepage: https://github.com/marcelobarreto/postgrest-rb
|
@@ -113,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
120
|
- !ruby/object:Gem::Version
|
114
121
|
version: '0'
|
115
122
|
requirements: []
|
116
|
-
rubygems_version: 3.0.
|
123
|
+
rubygems_version: 3.0.3
|
117
124
|
signing_key:
|
118
125
|
specification_version: 4
|
119
126
|
summary: Ruby client for PostgREST
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Postgrest
|
4
|
-
class QueryBuilder
|
5
|
-
attr_accessor :uri, :headers, :schema
|
6
|
-
|
7
|
-
def initialize(url:, headers:, schema:)
|
8
|
-
@uri = URI(url)
|
9
|
-
@headers = headers
|
10
|
-
@schema = schema
|
11
|
-
end
|
12
|
-
|
13
|
-
def select(columns = '*', options = {})
|
14
|
-
# @client.from('todos').select('*', { id: 'gt.35' })
|
15
|
-
|
16
|
-
Postgrest::HTTP.get(uri: uri, query: { select: columns }.merge(options), headers: headers)
|
17
|
-
end
|
18
|
-
|
19
|
-
def insert(values)
|
20
|
-
Postgrest::HTTP.post(uri: uri, body: values, headers: headers)
|
21
|
-
end
|
22
|
-
|
23
|
-
def update(values); end
|
24
|
-
|
25
|
-
def match(values); end
|
26
|
-
end
|
27
|
-
end
|
data/lib/postgrest/response.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Postgrest
|
4
|
-
class Response
|
5
|
-
attr_reader :error, :data, :count, :status, :status_text, :body
|
6
|
-
|
7
|
-
def initialize(params = {})
|
8
|
-
@error = params[:error]
|
9
|
-
@data = params[:data]
|
10
|
-
@count = params[:count]
|
11
|
-
@status = params[:status]
|
12
|
-
@status_text = params[:status_text]
|
13
|
-
@body = params[:body]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|