Compare commits

...
14 Commits
Author SHA1 Message Date
Joe Nelson 6cc493da6b Version 0.2.12.1 2015-11-12 11:06:11 -08:00
Joe Nelson 08fc83709c Merge pull request #352 from ruslantalpa/master
A simpler way for non haskell devs to install postgrest
2015-11-10 08:28:33 -08:00
Ruslan Talpa 92174dc0d2 modify build from source steps to also copy the bin to the right location (remove small comment) 2015-11-10 10:31:22 +02:00
Ruslan Talpa 2d72847d39 modify build from source steps to also copy the bin to the right location 2015-11-10 10:30:07 +02:00
Joe Nelson 4f7dd12133 Merge pull request #348 from xDAGRONx/homebrew
Add documentation for installing via Homebrew
2015-11-06 10:12:19 -08:00
JC Wilcox 8b16a1ee33 Add documentation for installing via Homebrew
Modify the server installation guide to include steps for installation
using Hombrew on OS X.
2015-11-06 10:23:33 -06:00
Joe Nelson 5e9d29e07b Merge pull request #340 from ruslantalpa/master
Fix for #334
2015-11-02 17:27:33 -08:00
Ruslan Talpa 5113187bb1 changelog update and lint fix 2015-11-02 23:35:59 +02:00
Ruslan Talpa ef08af359c Fix for #334 2015-11-02 14:44:45 +02:00
Joe Nelson 31c3edc183 Merge pull request #335 from PierreR/jsonb
Add a test case for issue #334
2015-10-30 13:10:51 -07:00
Pierre Radermecker 2cfe3651b4 Add a test case for issue #334 2015-10-30 19:16:59 +01:00
Joe Nelson 1c22b8d429 Merge pull request #333 from diogob/fix_empty_set_returning_function
Fixes 500 when set returning function returns an empty row set [fix #332]
2015-10-28 10:57:05 -07:00
Diogo Biazus c6956d0ff6 Adds fix to CHANGELOG 2015-10-28 09:17:25 -04:00
Diogo Biazus 4369a5617e Fixes 500 when set returning function returns an empty row set [fix #332] 2015-10-27 21:19:55 -04:00
9 changed files with 69 additions and 19 deletions
+6
View File
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). This project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.12.1] - 2015-11-12
### Fixed
- Correct order for -> and ->> in a json path - @ruslantalpa
- Return empty array instead of 500 when a set returning function returns an empty result set - @diogob
## [0.2.12.0] - 2015-10-25 ## [0.2.12.0] - 2015-10-25
### Added ### Added
+1 -1
View File
@@ -10,7 +10,7 @@
}, },
"POSTGREST_VER": { "POSTGREST_VER": {
"description": "Version of PostgREST to deploy", "description": "Version of PostgREST to deploy",
"value": "0.2.12.0" "value": "0.2.12.1"
}, },
"DB_NAME": { "DB_NAME": {
"description": "Database name", "description": "Database name",
+35 -8
View File
@@ -7,7 +7,7 @@ The [release page](https://github.com/begriffs/postgrest/releases/latest) has pr
```sh ```sh
# Untar the release (available at https://github.com/begriffs/postgrest/releases/latest) # Untar the release (available at https://github.com/begriffs/postgrest/releases/latest)
$ tar zxf postgrest-0.2.12.0-osx.tar.xz $ tar zxf postgrest-0.2.12.1-osx.tar.xz
# Try running it # Try running it
$ ./postgrest $ ./postgrest
@@ -22,13 +22,13 @@ $ ./postgrest
<ul><li>Scientific Linux 6</li><li>CentOS</li><li>RHEL 6</li></ul> <ul><li>Scientific Linux 6</li><li>CentOS</li><li>RHEL 6</li></ul>
Also it would be good to create packages for Homebrew, and apt.</p> Also it would be good to create a package for apt.</p>
</div> </div>
We'll learn the meaning of the command line flags later, but here is a minimal example of running the app. It does all operations as user `postgres`, including for unauthenticated requests. We'll learn the meaning of the command line flags later, but here is a minimal example of running the app. It does all operations as user `postgres`, including for unauthenticated requests.
```sh ```sh
$ ./postgrest -d dbname -U postgres --a postgres --v1schema public $ ./postgrest -d dbname -U postgres -a postgres --v1schema public
``` ```
### Building from Source ### Building from Source
@@ -36,27 +36,54 @@ $ ./postgrest -d dbname -U postgres --a postgres --v1schema public
When a prebuilt binary does not exist for your system you can build the project from source. You'll also need to do this if you want to help with development. [Stack](https://github.com/commercialhaskell/stack) makes it easy. It will install any necessary Haskell dependencies on your system. When a prebuilt binary does not exist for your system you can build the project from source. You'll also need to do this if you want to help with development. [Stack](https://github.com/commercialhaskell/stack) makes it easy. It will install any necessary Haskell dependencies on your system.
* [Install Stack](https://github.com/commercialhaskell/stack#how-to-install) for your platform * [Install Stack](https://github.com/commercialhaskell/stack#how-to-install) for your platform
* Build the project ```bash
#ubuntu example
wget -q -O- https://s3.amazonaws.com/download.fpcomplete.com/ubuntu/fpco.key | sudo apt-key add -
echo 'deb http://download.fpcomplete.com/ubuntu/trusty stable main'|sudo tee /etc/apt/sources.list.d/fpco.list
sudo apt-get update && sudo apt-get install stack -y
```
* Build & install in one step
```bash ```bash
git clone https://github.com/begriffs/postgrest.git git clone https://github.com/begriffs/postgrest.git
cd postgrest cd postgrest
stack build sudo stack install --install-ghc --local-bin-path /usr/local/bin
``` ```
* Run the server * Run the server
```bash ```bash
stack exec postgrest -- arg1 arg2 postgrest dbconnectionstring arg1 arg2
# ... your arguments after the double dashes
``` ```
If you want to run the test suite, stack can do that too: `stack test`. If you want to run the test suite, stack can do that too: `stack test`.
### Install via Homebrew (Mac OS X)
You can use the Homebrew package manager to install PostgREST on Mac
```bash
# Ensure brew is up to date
brew update
# Check for any problems with brew's setup
brew doctor
# Install the postgrest package
brew install postgrest
```
This will automatically install PostgreSQL as a dependency (see the [Installing PostgreSQL](#installing-postgresql) section for setup instructions). The process tends to take around 15 minutes to install the package and its dependencies.
After installation completes, the tool is added to your $PATH and can be used from anywhere with:
```bash
postgrest --help
```
### Installing PostgreSQL ### Installing PostgreSQL
To use PostgREST you will need an underlying database. You can use something like Amazon [RDS](https://aws.amazon.com/rds/) but installing your own locally is cheaper and more convenient for development. To use PostgREST you will need an underlying database. You can use something like Amazon [RDS](https://aws.amazon.com/rds/) but installing your own locally is cheaper and more convenient for development.
* [Instructions for OS X](http://exponential.io/blog/2015/02/21/install-postgresql-on-mac-os-x-via-brew/) * [Instructions for OS X](http://exponential.io/blog/2015/02/21/install-postgresql-on-mac-os-x-via-brew/)
* [Instructions for Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-14-04) * [Instructions for Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-14-04)
+1 -1
View File
@@ -2,7 +2,7 @@ name: postgrest
description: Reads the schema of a PostgreSQL database and creates RESTful routes description: Reads the schema of a PostgreSQL database and creates RESTful routes
for the tables and views, supporting all HTTP verbs that security for the tables and views, supporting all HTTP verbs that security
permits. permits.
version: 0.2.12.0 version: 0.2.12.1
synopsis: REST API for any Postgres database synopsis: REST API for any Postgres database
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
+6 -5
View File
@@ -18,6 +18,7 @@ import Data.Tree
import Network.Wai (Request, pathInfo, queryString) import Network.Wai (Request, pathInfo, queryString)
import PostgREST.Types import PostgREST.Types
import Text.ParserCombinators.Parsec hiding (many, (<|>)) import Text.ParserCombinators.Parsec hiding (many, (<|>))
parseGetRequest :: Request -> Either ParseError ApiRequest parseGetRequest :: Request -> Either ParseError ApiRequest
parseGetRequest httpRequest = parseGetRequest httpRequest =
foldr addFilter <$> (addOrder <$> apiRequest <*> ord) <*> flts foldr addFilter <$> (addOrder <$> apiRequest <*> ord) <*> flts
@@ -77,7 +78,7 @@ lexeme p = ws *> p <* ws
pTreePath :: Parser (Path,Field) pTreePath :: Parser (Path,Field)
pTreePath = do pTreePath = do
p <- pFieldName `sepBy1` pDelimiter p <- pFieldName `sepBy1` pDelimiter
jp <- optionMaybe ( string "->" >> pJsonPath) jp <- optionMaybe pJsonPath
let pp = map cs p let pp = map cs p
jpp = map cs <$> jp jpp = map cs <$> jp
return (init pp, (last pp, jpp)) return (init pp, (last pp, jpp))
@@ -98,14 +99,14 @@ pFieldName :: Parser Text
pFieldName = cs <$> (many1 (letter <|> digit <|> oneOf "_") pFieldName = cs <$> (many1 (letter <|> digit <|> oneOf "_")
<?> "field name (* or [a..z0..9_])") <?> "field name (* or [a..z0..9_])")
pJsonPathDelimiter :: Parser Text pJsonPathStep :: Parser Text
pJsonPathDelimiter = cs <$> (try (string "->>") <|> string "->") pJsonPathStep = cs <$> try (string "->" *> pFieldName)
pJsonPath :: Parser [Text] pJsonPath :: Parser [Text]
pJsonPath = pFieldName `sepBy1` pJsonPathDelimiter pJsonPath = (++) <$> many pJsonPathStep <*> ( (:[]) <$> (string "->>" *> pFieldName) )
pField :: Parser Field pField :: Parser Field
pField = lexeme $ (,) <$> pFieldName <*> optionMaybe ( pJsonPathDelimiter *> pJsonPath) pField = lexeme $ (,) <$> pFieldName <*> optionMaybe pJsonPath
pSelect :: Parser SelectItem pSelect :: Parser SelectItem
pSelect = lexeme $ pSelect = lexeme $
+1 -1
View File
@@ -116,7 +116,7 @@ asJsonWithCount = withCount . asJson
asJson :: StatementT asJson :: StatementT
asJson s = s { asJson s = s {
B.stmtTemplate = B.stmtTemplate =
"array_to_json(array_agg(row_to_json(t)))::character varying from (" "array_to_json(coalesce(array_agg(row_to_json(t)), '{}'))::character varying from ("
<> B.stmtTemplate s <> ") t" } <> B.stmtTemplate s <> ") t" }
withCount :: StatementT withCount :: StatementT
+9 -1
View File
@@ -296,12 +296,15 @@ spec =
describe "jsonb" $ do describe "jsonb" $ do
it "can filter by properties inside json column" $ do it "can filter by properties inside json column" $ do
get "/json?data->foo->>bar=eq.baz" `shouldRespondWith` get "/json?data->foo->>bar=eq.baz" `shouldRespondWith`
[json| [{"data": {"foo": {"bar": "baz"}}}] |] [json| [{"data": {"id": 1, "foo": {"bar": "baz"}}}] |]
get "/json?data->foo->>bar=eq.fake" `shouldRespondWith` get "/json?data->foo->>bar=eq.fake" `shouldRespondWith`
[json| [] |] [json| [] |]
it "can filter by properties inside json column using not" $ it "can filter by properties inside json column using not" $
get "/json?data->foo->>bar=not.eq.baz" `shouldRespondWith` get "/json?data->foo->>bar=not.eq.baz" `shouldRespondWith`
[json| [] |] [json| [] |]
it "can filter by properties inside json column using ->>" $
get "/json?data->>id=eq.1" `shouldRespondWith`
[json| [{"data": {"id": 1, "foo": {"bar": "baz"}}}] |]
describe "remote procedure call" $ do describe "remote procedure call" $ do
context "a proc that returns a set" . before_ (clearTable "items" >> createItems 10) . context "a proc that returns a set" . before_ (clearTable "items" >> createItems 10) .
@@ -310,6 +313,11 @@ spec =
post "/rpc/getitemrange" [json| { "min": 2, "max": 4 } |] `shouldRespondWith` post "/rpc/getitemrange" [json| { "min": 2, "max": 4 } |] `shouldRespondWith`
[json| [ {"id": 3}, {"id":4} ] |] [json| [ {"id": 3}, {"id":4} ] |]
context "a proc that returns an empty rowset" $
it "returns empty json array" $
post "/rpc/test_empty_rowset" [json| {} |] `shouldRespondWith`
[json| [] |]
context "a proc that returns plain text" $ context "a proc that returns plain text" $
it "returns proper json" $ it "returns proper json" $
post "/rpc/sayhello" [json| { "name": "world" } |] `shouldRespondWith` post "/rpc/sayhello" [json| { "name": "world" } |] `shouldRespondWith`
+3 -1
View File
@@ -184,4 +184,6 @@ createJsonData = do
[H.stmt| [H.stmt|
insert into "1".json (data) values (?) insert into "1".json (data) values (?)
|] |]
(J.object [("foo", J.object [("bar", J.String "baz")])]) (J.object [("id", J.Number 1)
,("foo", J.object [("bar", J.String "baz")])
])
+7 -1
View File
@@ -297,7 +297,9 @@ CREATE FUNCTION "1".getitemrange(min bigint, max bigint) RETURNS SETOF "1".items
SELECT * FROM "1".items WHERE id > $1 AND id <= $2; SELECT * FROM "1".items WHERE id > $1 AND id <= $2;
$$ LANGUAGE SQL; $$ LANGUAGE SQL;
CREATE FUNCTION "1".test_empty_rowset() RETURNS SETOF int AS $$
SELECT null::int FROM (SELECT 1) a WHERE false;
$$ LANGUAGE SQL;
CREATE FUNCTION "1".sayhello(name text) RETURNS text AS $$ CREATE FUNCTION "1".sayhello(name text) RETURNS text AS $$
SELECT 'Hello, ' || $1; SELECT 'Hello, ' || $1;
@@ -663,6 +665,10 @@ REVOKE ALL ON FUNCTION getitemrange(bigint, bigint) FROM postgrest_test;
GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_test; GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_test;
GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_anonymous; GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_anonymous;
REVOKE ALL ON FUNCTION test_empty_rowset() FROM PUBLIC;
REVOKE ALL ON FUNCTION test_empty_rowset() FROM postgrest_test;
GRANT EXECUTE ON FUNCTION test_empty_rowset() TO postgrest_test;
GRANT EXECUTE ON FUNCTION test_empty_rowset() TO postgrest_anonymous;
REVOKE ALL ON FUNCTION sayhello(text) FROM PUBLIC; REVOKE ALL ON FUNCTION sayhello(text) FROM PUBLIC;
REVOKE ALL ON FUNCTION sayhello(text) FROM postgrest_test; REVOKE ALL ON FUNCTION sayhello(text) FROM postgrest_test;