Safe Haskell | None |
---|
Haskell client driver for RethinkDB
Based upon the official Javascript, Python and Ruby API: http://www.rethinkdb.com/api/
How to use
{-# LANGUAGE OverloadedStrings #-} import qualified Database.RethinkDB as R import qualified Database.RethinkDB.NoClash
- connect :: HostName -> Integer -> Maybe String -> IO RethinkDBHandle
- data RethinkDBHandle
- close :: RethinkDBHandle -> IO ()
- use :: Database -> RethinkDBHandle -> RethinkDBHandle
- run :: (Expr query, Result r) => RethinkDBHandle -> query -> IO r
- run' :: Expr query => RethinkDBHandle -> query -> IO Datum
- runOpts :: (Expr query, Result r) => RethinkDBHandle -> [RunFlag] -> query -> IO r
- data ReQL
- data Datum
- class ToDatum a where
- class FromDatum a where
- parseDatum :: Datum -> Parser a
- fromDatum :: FromDatum a => Datum -> Result a
- data RunFlag
- = UseOutdated
- | NoReply
- | Durability Durability
- | Profile
- | ArrayLimit Int
- noReplyWait :: RethinkDBHandle -> IO ()
- data RethinkDBError = RethinkDBError {
- errorCode :: ErrorCode
- errorTerm :: Term
- errorMessage :: String
- errorBacktrace :: Backtrace
- data ErrorCode
- data Response
- class Result r where
- convertResult :: MVar Response -> IO r
- next :: Cursor a -> IO (Maybe a)
- collect :: Cursor a -> IO [a]
- collect' :: Cursor a -> IO [a]
- each :: Cursor a -> (a -> IO b) -> IO ()
- data Cursor a
- data Database = Database {
- databaseName :: Text
- dbCreate :: String -> ReQL
- dbDrop :: Database -> ReQL
- dbList :: ReQL
- data Table = Table {
- tableDatabase :: Maybe Database
- tableName :: Text
- tablePrimaryKey :: Maybe Key
- tableCreate :: Table -> ReQL
- tableDrop :: Table -> ReQL
- tableList :: Database -> ReQL
- indexCreate :: Expr fun => String -> fun -> Table -> ReQL
- indexDrop :: Key -> Table -> ReQL
- indexList :: Table -> ReQL
- indexRename :: Expr table => ReQL -> ReQL -> table -> ReQL
- indexStatus :: Expr table => [ReQL] -> table -> ReQL
- indexWait :: Expr table => [ReQL] -> table -> ReQL
- changes :: Expr seq => seq -> ReQL
- data WriteResponse = WriteResponse {
- writeResponseInserted :: Int
- writeResponseDeleted :: Int
- writeResponseReplaced :: Int
- writeResponseUnchanged :: Int
- writeResponseSkipped :: Int
- writeResponseErrors :: Int
- writeResponseFirstError :: Maybe Text
- writeResponseGeneratedKeys :: Maybe [Text]
- writeResponseChanges :: Maybe [Change]
- data Change = Change {}
- insert :: Expr object => object -> Table -> ReQL
- update :: (Expr selection, Expr a) => (ReQL -> a) -> selection -> ReQL
- replace :: (Expr selection, Expr a) => (ReQL -> a) -> selection -> ReQL
- delete :: Expr selection => selection -> ReQL
- sync :: Expr table => table -> ReQL
- returnChanges :: Attribute a
- nonAtomic :: Attribute a
- durability :: Durability -> Attribute a
- data Durability
- conflict :: ConflictResolution -> Attribute a
- data ConflictResolution
- db :: Text -> Database
- table :: Text -> Table
- get :: Expr s => ReQL -> s -> ReQL
- getAll :: Expr values => Index -> values -> Table -> ReQL
- filter :: (Expr predicate, Expr seq) => predicate -> seq -> ReQL
- between :: (Expr left, Expr right, Expr seq) => Index -> Bound left -> Bound right -> seq -> ReQL
- data Bound a
- innerJoin :: (Expr a, Expr b, Expr c) => (ReQL -> ReQL -> c) -> a -> b -> ReQL
- outerJoin :: (Expr a, Expr b, Expr c) => (ReQL -> ReQL -> c) -> a -> b -> ReQL
- eqJoin :: (Expr fun, Expr right, Expr left) => fun -> right -> Index -> left -> ReQL
- zip :: Expr a => a -> ReQL
- data Index
- = PrimaryKey
- | Index Key
- map :: (Expr a, Expr b) => (ReQL -> b) -> a -> ReQL
- withFields :: Expr seq => [ReQL] -> seq -> ReQL
- concatMap :: (Expr a, Expr b) => (ReQL -> b) -> a -> ReQL
- orderBy :: Expr s => [ReQL] -> s -> ReQL
- asc :: ReQL -> ReQL
- desc :: ReQL -> ReQL
- skip :: (Expr n, Expr seq) => n -> seq -> ReQL
- limit :: (Expr n, Expr seq) => n -> seq -> ReQL
- slice :: (Expr a, Expr b, Expr c) => a -> b -> c -> ReQL
- indexesOf :: (Expr fun, Expr seq) => fun -> seq -> ReQL
- isEmpty :: Expr seq => seq -> ReQL
- union :: (Expr a, Expr b) => a -> b -> ReQL
- sample :: (Expr n, Expr seq) => n -> seq -> ReQL
- group :: (Expr group, Expr reduction, Expr seq) => (ReQL -> group) -> (ReQL -> reduction) -> seq -> ReQL
- reduce :: (Expr a, Expr s) => (ReQL -> ReQL -> a) -> s -> ReQL
- reduce0 :: (Expr base, Expr seq, Expr a) => (ReQL -> ReQL -> a) -> base -> seq -> ReQL
- distinct :: Expr s => s -> ReQL
- contains :: (Expr x, Expr seq) => x -> seq -> ReQL
- mapReduce :: (Expr reduction, Expr seq) => (ReQL -> reduction) -> seq -> ReQL
- count :: Expr a => a -> ReQL
- sum :: Expr s => s -> ReQL
- avg :: Expr s => s -> ReQL
- min :: Expr s => s -> ReQL
- max :: Expr s => s -> ReQL
- argmin :: (Expr s, Expr a) => (ReQL -> a) -> s -> ReQL
- argmax :: (Expr s, Expr a) => (ReQL -> a) -> s -> ReQL
- pluck :: Expr o => [ReQL] -> o -> ReQL
- without :: Expr o => [ReQL] -> o -> ReQL
- merge :: (Expr a, Expr b) => a -> b -> ReQL
- append :: (Expr a, Expr b) => a -> b -> ReQL
- prepend :: (Expr datum, Expr array) => datum -> array -> ReQL
- difference :: (Expr a, Expr b) => a -> b -> ReQL
- setInsert :: (Expr datum, Expr array) => datum -> array -> ReQL
- setUnion :: (Expr a, Expr b) => a -> b -> ReQL
- setIntersection :: (Expr a, Expr b) => a -> b -> ReQL
- setDifference :: (Expr set, Expr remove) => remove -> set -> ReQL
- (!) :: Expr s => s -> ReQL -> ReQL
- (!?) :: Expr s => s -> ReQL -> ReQL
- hasFields :: Expr obj => ReQL -> obj -> ReQL
- insertAt :: (Expr n, Expr datum, Expr array) => n -> datum -> array -> ReQL
- spliceAt :: (Expr n, Expr replace, Expr array) => n -> replace -> array -> ReQL
- deleteAt :: (Expr n, Expr array) => n -> array -> ReQL
- changeAt :: (Expr n, Expr datum, Expr array) => n -> datum -> array -> ReQL
- keys :: Expr object => object -> ReQL
- literal :: Expr a => a -> ReQL
- remove :: ReQL
- data Attribute a where
- match :: Expr string => ReQL -> string -> ReQL
- upcase :: Expr str => str -> ReQL
- downcase :: Expr str => str -> ReQL
- split :: Expr str => str -> ReQL
- splitOn :: Expr str => ReQL -> str -> ReQL
- splitMax :: Expr str => ReQL -> ReQL -> str -> ReQL
- (+) :: (Expr a, Expr b) => a -> b -> ReQL
- (-) :: (Expr a, Expr b) => a -> b -> ReQL
- (*) :: (Expr a, Expr b) => a -> b -> ReQL
- (/) :: (Expr a, Expr b) => a -> b -> ReQL
- mod :: (Expr a, Expr b) => a -> b -> ReQL
- (&&) :: (Expr a, Expr b) => a -> b -> ReQL
- (||) :: (Expr a, Expr b) => a -> b -> ReQL
- (==) :: (Expr a, Expr b) => a -> b -> ReQL
- (/=) :: (Expr a, Expr b) => a -> b -> ReQL
- (>) :: (Expr a, Expr b) => a -> b -> ReQL
- (>=) :: (Expr a, Expr b) => a -> b -> ReQL
- (<) :: (Expr a, Expr b) => a -> b -> ReQL
- (<=) :: (Expr a, Expr b) => a -> b -> ReQL
- not :: Expr a => a -> ReQL
- random :: ReQL
- randomTo :: ReQL -> ReQL
- randomFromTo :: ReQL -> ReQL -> ReQL
- now :: ReQL
- time :: ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL
- epochTime :: ReQL -> ReQL
- iso8601 :: ReQL -> ReQL
- inTimezone :: Expr time => ReQL -> time -> ReQL
- during :: (Expr left, Expr right, Expr time) => Bound left -> Bound right -> time -> ReQL
- timezone :: Expr time => time -> ReQL
- date :: Expr time => time -> ReQL
- timeOfDay :: Expr time => time -> ReQL
- year :: Expr time => time -> ReQL
- month :: Expr time => time -> ReQL
- day :: Expr time => time -> ReQL
- dayOfWeek :: Expr time => time -> ReQL
- dayOfYear :: Expr time => time -> ReQL
- hours :: Expr time => time -> ReQL
- minutes :: Expr time => time -> ReQL
- seconds :: Expr time => time -> ReQL
- toIso8601 :: Expr t => t -> ReQL
- toEpochTime :: Expr t => t -> ReQL
- args :: Expr array => array -> ReQL
- apply :: (Expr fun, Expr arg) => fun -> [arg] -> ReQL
- js :: ReQL -> ReQL
- branch :: (Expr a, Expr b, Expr c) => a -> b -> c -> ReQL
- forEach :: (Expr s, Expr a) => s -> (ReQL -> a) -> ReQL
- error :: Expr s => s -> ReQL
- handle :: (Expr instead, Expr reql) => (ReQL -> instead) -> reql -> ReQL
- class Expr e where
- coerceTo :: Expr x => ReQL -> x -> ReQL
- asArray :: Expr x => x -> ReQL
- asString :: Expr x => x -> ReQL
- asNumber :: Expr x => x -> ReQL
- asObject :: Expr x => x -> ReQL
- asBool :: Expr x => x -> ReQL
- typeOf :: Expr a => a -> ReQL
- info :: Expr a => a -> ReQL
- json :: ReQL -> ReQL
- uuid :: ReQL
- http :: Expr url => url -> HttpOptions -> ReQL
- data HttpOptions = HttpOptions {
- httpTimeout :: Maybe Int
- httpReattempts :: Maybe Int
- httpRedirects :: Maybe Int
- httpVerify :: Maybe Bool
- httpResultFormat :: Maybe HttpResultFormat
- httpMethod :: Maybe HttpMethod
- httpAuth :: Maybe [Attribute Dynamic]
- httpParams :: Maybe [Attribute Dynamic]
- httpHeader :: Maybe [Attribute Dynamic]
- httpData :: Maybe ReQL
- httpPage :: Maybe PaginationStrategy
- httpPageLimit :: Maybe Int
- data HttpResultFormat
- = FormatAuto
- | FormatJSON
- | FormatJSONP
- | FormatBinary
- data HttpMethod
- data PaginationStrategy
- = LinkNext
- | PaginationFunction (ReQL -> ReQL)
- circle :: (Expr point, Expr radius) => point -> radius -> ReQL
- distance :: (Expr a, Expr b) => a -> b -> ReQL
- fill :: Expr line => line -> ReQL
- geoJSON :: Expr geojson => geojson -> ReQL
- toGeoJSON :: Expr geo => geo -> ReQL
- getIntersecting :: (Expr geo, Expr table) => geo -> Index -> table -> ReQL
- getNearest :: (Expr point, Expr table) => point -> Index -> table -> ReQL
- includes :: (Expr area, Expr geo) => geo -> area -> ReQL
- intersects :: (Expr a, Expr b) => a -> b -> ReQL
- line :: Expr points => points -> ReQL
- point :: (Expr longitude, Expr latitude) => longitude -> latitude -> ReQL
- polygon :: Expr points => points -> ReQL
- polygonSub :: (Expr polygon, Expr hole) => hole -> polygon -> ReQL
- data LonLat = LonLat {}
- type Line = Vector LonLat
- type Polygon = Vector (Vector LonLat)
- maxResults :: ReQL -> Attribute a
- maxDist :: ReQL -> Attribute a
- unit :: Unit -> Attribute a
- numVertices :: ReQL -> Attribute a
- data Unit
- = Meter
- | Kilometer
- | Mile
- | NauticalMile
- | Foot
- ex :: OptArgs a => a -> [Attribute Static] -> a
- str :: String -> ReQL
- num :: Double -> ReQL
- (#) :: (Expr a, Expr b) => a -> (a -> b) -> ReQL
- note :: String -> ReQL -> ReQL
- empty :: ReQL
- def :: Default a => a
Accessing RethinkDB
connect :: HostName -> Integer -> Maybe String -> IO RethinkDBHandleSource
Create a new connection to the database server
Example: connect using the default port with no passphrase
>>>
h <- connect "localhost" 28015 Nothing
close :: RethinkDBHandle -> IO ()Source
Close an open connection
use :: Database -> RethinkDBHandle -> RethinkDBHandleSource
Set the default database
The new handle is an alias for the old one. Calling close on either one will close both.
run :: (Expr query, Result r) => RethinkDBHandle -> query -> IO rSource
Run a given query and return a Result
run' :: Expr query => RethinkDBHandle -> query -> IO DatumSource
Run a given query and return a Datum
runOpts :: (Expr query, Result r) => RethinkDBHandle -> [RunFlag] -> query -> IO rSource
Run a query with the given options
A ReQL Term
A ReQL value
ToDatum Bool | |
ToDatum Char | |
ToDatum Double | |
ToDatum Float | |
ToDatum Int | |
ToDatum Int8 | |
ToDatum Int16 | |
ToDatum Int32 | |
ToDatum Int64 | |
ToDatum Integer | |
ToDatum Word | |
ToDatum Word8 | |
ToDatum Word16 | |
ToDatum Word32 | |
ToDatum Word64 | |
ToDatum () | |
ToDatum ByteString | |
ToDatum ByteString | |
ToDatum Text | |
ToDatum UTCTime | |
ToDatum Value | |
ToDatum Text | |
ToDatum ZonedTime | |
ToDatum Datum | |
ToDatum [Char] | |
ToDatum a => ToDatum [a] | |
ToDatum (Ratio Integer) | |
ToDatum a => ToDatum (Maybe a) | |
ToDatum a => ToDatum (Vector a) | |
ToDatum a => ToDatum (Set a) | |
(ToDatum a, ToDatum b) => ToDatum (Either a b) | |
(ToDatum a, ToDatum b) => ToDatum (a, b) | |
ToDatum a => ToDatum (HashMap [Char] a) | |
ToDatum a => ToDatum (HashMap Text a) | |
ToDatum a => ToDatum (Map [Char] a) | |
ToDatum a => ToDatum (Map Text a) | |
(ToDatum a, ToDatum b, ToDatum c) => ToDatum (a, b, c) | |
(ToDatum a, ToDatum b, ToDatum c, ToDatum d) => ToDatum (a, b, c, d) | |
(ToDatum a, ToDatum b, ToDatum c, ToDatum d, ToDatum e) => ToDatum (a, b, c, d, e) |
parseDatum :: Datum -> Parser aSource
Per-query settings
UseOutdated | |
NoReply | |
Durability Durability | |
Profile | |
ArrayLimit Int |
noReplyWait :: RethinkDBHandle -> IO ()Source
Wait for NoReply queries to complete on the server
>>>
() <- runOpts h [NoReply] $ table "users" # get "bob" # update (\row -> merge row ["occupation" := "teacher"])
>>>
noReplyWait h
data RethinkDBError Source
RethinkDBError | |
|
Show RethinkDBError | |
Typeable RethinkDBError | |
Exception RethinkDBError |
Show ErrorCode |
Convert the raw query response into useful values
convertResult :: MVar Response -> IO rSource
Cursors
Manipulating databases
A database, referenced by name
dbCreate :: String -> ReQLSource
Create a database on the server
>>>
run' h $ dbCreate "dev"
{"created":1}
Manipulating Tables
A table description
Table | |
|
tableCreate :: Table -> ReQLSource
Create a table on the server
>>> run' h $ tableCreate (table "posts") def [{"created":1}] >>> run' h $ tableCreate (table "users"){ tablePrimaryKey = Just "name" } def [{"created":1}] >>> run' h $ tableCreate (Table (Just "doctests") "bar" (Just "name")) def [{"created":1}] >>> run' h $ ex tableCreate ["datacenter":="orion"] (Table (Just "doctests") "bar" (Just "name")) def [{"created":1}]
tableList :: Database -> ReQLSource
List the tables in a database
>>>
fmap sort $ run h $ tableList (db "doctests") :: IO [String]
["places","posts","users"]
indexCreate :: Expr fun => String -> fun -> Table -> ReQLSource
Create an index on the table from the given function
>>>
run' h $ table "users" # indexCreate "occupation" (!"occupation")
{"created":1}>>>
run' h $ table "users" # ex indexCreate ["multi":=True] "friends" (!"friends")
{"created":1}>>>
run' h $ table "users" # ex indexCreate ["geo":=True] "location" (!"location")
{"created":1}
indexDrop :: Key -> Table -> ReQLSource
Drop an index
>>>
run' h $ table "users" # indexDrop "occupation"
{"dropped":1}
indexList :: Table -> ReQLSource
List the indexes on the table
>>>
run' h $ indexList (table "users")
["friends","location","occupation"]
indexStatus :: Expr table => [ReQL] -> table -> ReQLSource
Get the status of the given indexes
run' h $ table "users" # indexStatus []
indexWait :: Expr table => [ReQL] -> table -> ReQLSource
Wait for an index to be built
run' h $ table "users" # indexWait []
changes :: Expr seq => seq -> ReQLSource
Return an infinite stream of objects representing changes to a table
>>>
cursor <- run h $ table "posts" # changes :: IO (Cursor Datum)
>>>
run h $ table "posts" # insert ["author" := "bill", "message" := "bye", "id" := 4] :: IO WriteResponse
{inserted:1}>>>
next cursor
Just {"new_val":{"author":"bill","id":4,"message":"bye"},"old_val":null}
Writing data
data WriteResponse Source
WriteResponse | |
|
insert :: Expr object => object -> Table -> ReQLSource
Insert a document or a list of documents into a table
>>>
run h $ table "users" # insert (map (\x -> ["name":=x]) ["bill", "bob", "nancy" :: Text]) :: IO WriteResponse
{inserted:3}>>>
run h $ table "posts" # insert ["author" := str "bill", "message" := str "hi", "id" := 1] :: IO WriteResponse
{inserted:1}>>>
run h $ table "posts" # insert ["author" := str "bill", "message" := str "hello", "id" := 2, "flag" := str "deleted"] :: IO WriteResponse
{inserted:1}>>>
run h $ table "posts" # insert ["author" := str "bob", "message" := str "lorem ipsum", "id" := 3, "flag" := str "pinned"] :: IO WriteResponse
{inserted:1}
update :: (Expr selection, Expr a) => (ReQL -> a) -> selection -> ReQLSource
Add to or modify the contents of a document
>>>
run h $ table "users" # getAll "name" [str "bob"] # update (const ["occupation" := str "tailor"]) :: IO WriteResponse
{replaced:1}
replace :: (Expr selection, Expr a) => (ReQL -> a) -> selection -> ReQLSource
Replace a document with another
>>>
run h $ replace (\user -> ["name" := user!"name", "occupation" := str "clothier"]) . R.filter ((R.== str "tailor") . (!?"occupation")) $ table "users" :: IO WriteResponse
{replaced:1}
delete :: Expr selection => selection -> ReQLSource
Delete the documents
>>>
run h $ delete . getAll "name" [str "bob"] $ table "users" :: IO WriteResponse
{deleted:1}
sync :: Expr table => table -> ReQLSource
Ensures that writes on a given table are written to permanent storage
>>>
run' h $ sync (table "users")
{"synced":1}
returnChanges :: Attribute aSource
Optional argument for returning an array of objects describing the changes made
>>>
run h $ table "users" # ex insert [returnChanges] ["name" := "sabrina"] :: IO WriteResponse
{inserted:1,changes:[{"old_val":null,"new_val":{"name":"sabrina"}}]}
nonAtomic :: Attribute aSource
Optional argument for non-atomic writes
>>>
run' h $ table "users" # get "sabrina" # update (merge ["lucky_number" := random])
*** Exception: RethinkDB: Runtime error: "Could not prove function deterministic. Maybe you want to use the non_atomic flag?" in {- HERE -} update( get(table(db("doctests"), "users"), "sabrina"), (\b -> merge(b, {lucky_number: random()})))>>>
run h $ table "users" # get "sabrina" # ex update [nonAtomic] (merge ["lucky_number" := random]) :: IO WriteResponse
{replaced:1}
durability :: Durability -> Attribute aSource
Optional argument for soft durability writes
Selecting data
Create a Database reference
>>>
run' h $ db "test" # info
{"name":"test","type":"DB"}
A table
>>>
fmap sort $ run h $ table "users" :: IO [Datum]
[{"post_count":2,"name":"bill"},{"post_count":0,"name":"nancy"}]
get :: Expr s => ReQL -> s -> ReQLSource
Get a document by primary key
>>>
run' h $ table "users" # get "nancy"
{"post_count":0,"name":"nancy"}
getAll :: Expr values => Index -> values -> Table -> ReQLSource
Retreive documents by their indexed value
>>>
run' h $ table "users" # getAll PrimaryKey [str "bill"]
[{"post_count":2,"name":"bill"}]
filter :: (Expr predicate, Expr seq) => predicate -> seq -> ReQLSource
Filter a sequence given a predicate
>>>
run h $ R.filter (R.< 4) [3, 1, 4, 1, 5, 9, 2, 6]
[3,1,1,2]
between :: (Expr left, Expr right, Expr seq) => Index -> Bound left -> Bound right -> seq -> ReQLSource
Query all the documents whose value for the given index is in a given range
>>>
run h $ table "users" # between "name" (Closed $ str "a") (Open $ str "c")
[{"post_count":2,"name":"bill"}]
An upper or lower bound for between and during
Joins
innerJoin :: (Expr a, Expr b, Expr c) => (ReQL -> ReQL -> c) -> a -> b -> ReQLSource
SQL-like inner join of two sequences
>>>
run' h $ innerJoin (\user post -> user!"name" R.== post!"author") (table "users") (table "posts") # R.zip # orderBy [asc "id"] # pluck ["name", "message"]
[{"name":"bill","message":"hi"},{"name":"bill","message":"hello"}]
outerJoin :: (Expr a, Expr b, Expr c) => (ReQL -> ReQL -> c) -> a -> b -> ReQLSource
SQL-like outer join of two sequences
>>>
run' h $ outerJoin (\user post -> user!"name" R.== post!"author") (table "users") (table "posts") # R.zip # orderBy [asc "id", asc "name"] # pluck ["name", "message"]
[{"name":"nancy"},{"name":"bill","message":"hi"},{"name":"bill","message":"hello"}]
eqJoin :: (Expr fun, Expr right, Expr left) => fun -> right -> Index -> left -> ReQLSource
An efficient inner_join that uses a key for the left table and an index for the right table.
>>>
run' h $ table "posts" # eqJoin "author" (table "users") "name" # R.zip # orderBy [asc "id"] # pluck ["name", "message"]
[{"name":"bill","message":"hi"},{"name":"bill","message":"hello"}]
zip :: Expr a => a -> ReQLSource
Merge the left and right attributes of the objects in a sequence.
>>>
fmap sort $ run h $ table "posts" # eqJoin "author" (table "users") "name" # R.zip :: IO [Datum]
[{"post_count":2,"flag":"deleted","name":"bill","author":"bill","id":2,"message":"hello"},{"post_count":2,"name":"bill","author":"bill","id":1,"message":"hi"}]
Transformations
map :: (Expr a, Expr b) => (ReQL -> b) -> a -> ReQLSource
Map a function over a sequence
>>>
run h $ R.map (!"a") [["a" := 1], ["a" := 2]]
[1,2]
withFields :: Expr seq => [ReQL] -> seq -> ReQLSource
Like hasFields followed by pluck
>>>
run' h $ [["a" := 1, "b" := 2], ["a" := 2, "c" := 7], ["b" := 4]] # withFields ["a"]
[{"a":1},{"a":2}]
concatMap :: (Expr a, Expr b) => (ReQL -> b) -> a -> ReQLSource
Map a function of a sequence and concat the results
>>>
run h $ concatMap id [[1, 2], [3], [4, 5]]
[1,2,3,4,5]
orderBy :: Expr s => [ReQL] -> s -> ReQLSource
Order a sequence by the given keys
>>>
run' h $ table "users" # orderBy [desc "post_count", asc "name"] # pluck ["name", "post_count"]
[{"post_count":2,"name":"bill"},{"post_count":0,"name":"nancy"}]
>>>
run' h $ table "users" # ex orderBy ["index":="name"] [] # pluck ["name"]
[{"name":"bill"},{"name":"nancy"}]
skip :: (Expr n, Expr seq) => n -> seq -> ReQLSource
Drop elements from the head of a sequence.
>>>
run h $ skip 2 [1, 2, 3, 4]
[3,4]
limit :: (Expr n, Expr seq) => n -> seq -> ReQLSource
Limit the size of a sequence.
>>>
run h $ limit 2 [1, 2, 3, 4]
[1,2]
slice :: (Expr a, Expr b, Expr c) => a -> b -> c -> ReQLSource
Cut out part of a sequence
>>>
run h $ slice 2 4 [1, 2, 3, 4, 5]
[3,4]
indexesOf :: (Expr fun, Expr seq) => fun -> seq -> ReQLSource
The position in the sequence of the elements that match the predicate
>>>
run h $ indexesOf (match "ba.") [str "foo", "bar", "baz"]
[1,2]
union :: (Expr a, Expr b) => a -> b -> ReQLSource
Join two sequences.
>>>
run h $ [1,2,3] `union` ["a", "b", "c" :: Text]
[1,2,3,"a","b","c"]
sample :: (Expr n, Expr seq) => n -> seq -> ReQLSource
Select a given number of elements from a sequence with uniform random distribution
>>>
_ <- run' h $ sample 3 [0,1,2,3,4,5,6,7,8,9]
Aggregation
group :: (Expr group, Expr reduction, Expr seq) => (ReQL -> group) -> (ReQL -> reduction) -> seq -> ReQLSource
Turn a grouping function and a reduction function into a grouped map reduce operation
>>>
run' h $ table "posts" # group (!"author") (reduce (\a b -> a + "\n" + b) . R.map (!"message"))
[{"group":"bill","reduction":"hi\nhello"},{"group":"bob","reduction":"lorem ipsum"}]>>>
run' h $ table "users" # group ((!0) . splitOn "" . (!"name")) (\users -> let pc = users!"post_count" in [avg pc, R.sum pc])
[{"group":"b","reduction":[2,2]},{"group":"n","reduction":[0,0]}]
reduce :: (Expr a, Expr s) => (ReQL -> ReQL -> a) -> s -> ReQLSource
Reduce a non-empty sequence to a single value
>>>
run h $ reduce (+) [1, 2, 3]
6
reduce0 :: (Expr base, Expr seq, Expr a) => (ReQL -> ReQL -> a) -> base -> seq -> ReQLSource
Reduce a sequence to a single value
>>>
run h $ reduce0 (+) 0 [1, 2, 3]
6
distinct :: Expr s => s -> ReQLSource
Filter out identical elements of the sequence
>>>
fmap sort $ run h $ distinct (table "posts" ! "flag") :: IO [String]
["deleted","pinned"]
contains :: (Expr x, Expr seq) => x -> seq -> ReQLSource
Test if a sequence contains a given element
>>>
run' h $ [1,2,3] # contains 1
true
mapReduce :: (Expr reduction, Expr seq) => (ReQL -> reduction) -> seq -> ReQLSource
Rewrite multiple reductions into a single map/reduce operation
Aggregators
count :: Expr a => a -> ReQLSource
The size of a sequence or an array.
>>>
run h $ count (table "users")
2
Document manipulation
pluck :: Expr o => [ReQL] -> o -> ReQLSource
Keep only the given attributes
>>>
run' h $ [["a" := 1, "b" := 2], ["a" := 2, "c" := 7], ["b" := 4]] # pluck ["a"]
[{"a":1},{"a":2},{}]
without :: Expr o => [ReQL] -> o -> ReQLSource
Remove the given attributes from an object
>>>
run' h $ [["a" := 1, "b" := 2], ["a" := 2, "c" := 7], ["b" := 4]] # without ["a"]
[{"b":2},{"c":7},{"b":4}]
merge :: (Expr a, Expr b) => a -> b -> ReQLSource
Merge two objects together
>>>
run' h $ merge ["a" := 1, "b" := 1] ["b" := 1, "c" := 2]
{"a":1,"b":1,"c":2}
append :: (Expr a, Expr b) => a -> b -> ReQLSource
Append a datum to a sequence
>>>
run h $ append 3 [1, 2]
[1,2,3]
prepend :: (Expr datum, Expr array) => datum -> array -> ReQLSource
Prepend an element to an array
>>>
run h $ prepend 1 [2,3]
[1,2,3]
difference :: (Expr a, Expr b) => a -> b -> ReQLSource
The different of two lists
>>>
run h $ [1,2,3,4,5] # difference [2,5]
[1,3,4]
setInsert :: (Expr datum, Expr array) => datum -> array -> ReQLSource
Insert a datum into an array if it is not yet present
>>>
run h $ setInsert 3 [1,2,4,4,5]
[1,2,4,5,3]
setUnion :: (Expr a, Expr b) => a -> b -> ReQLSource
The union of two sets
>>>
run h $ [1,2] `setUnion` [2,3]
[2,3,1]
setIntersection :: (Expr a, Expr b) => a -> b -> ReQLSource
The intersection of two sets
>>>
run h $ [1,2] `setIntersection` [2,3]
[2]
setDifference :: (Expr set, Expr remove) => remove -> set -> ReQLSource
The difference of two sets
>>>
run h $ [2,3] # setDifference [1,2]
[3]
(!) :: Expr s => s -> ReQL -> ReQLSource
Get a single field from an object or an element of an array
>>>
run h $ ["foo" := True] ! "foo"
true
>>>
run h $ [1, 2, 3] ! 0
1
Or a single field from each object in a sequence
>>>
run h $ [["foo" := True], ["foo" := False]] ! "foo"
[true,false]
(!?) :: Expr s => s -> ReQL -> ReQLSource
Get a single field, or null if not present
>>>
run' h $ empty !? "foo"
null
hasFields :: Expr obj => ReQL -> obj -> ReQLSource
Test if an object has the given fields
>>>
run h $ hasFields "a" $ ["a" := 1]
true
insertAt :: (Expr n, Expr datum, Expr array) => n -> datum -> array -> ReQLSource
Insert a datum at the given position in an array
>>>
run h $ insertAt 1 4 [1,2,3]
[1,4,2,3]
spliceAt :: (Expr n, Expr replace, Expr array) => n -> replace -> array -> ReQLSource
Splice an array at a given position inside another array
>>>
run h $ spliceAt 2 [4,5] [1,2,3]
[1,2,4,5,3]
deleteAt :: (Expr n, Expr array) => n -> array -> ReQLSource
Delete an element from an array
>>>
run h $ deleteAt 1 [1,2,3]
[1,3]
changeAt :: (Expr n, Expr datum, Expr array) => n -> datum -> array -> ReQLSource
Change an element in an array
>>>
run h $ changeAt 1 4 [1,2,3]
[1,4,3]
keys :: Expr object => object -> ReQLSource
The list of keys of the given object
>>>
run h $ keys ["a" := 1, "b" := 2]
["a","b"]
literal :: Expr a => a -> ReQLSource
Literal objects, in a merge or update, are not processed recursively.
>>>
run' h $ ["a" := ["b" := 1]] # merge ["a" := literal ["c" := 2]]
{"a":{"c":2}}
Remove fields when doing a merge or update
>>>
run' h $ ["a" := ["b" := 1]] # merge ["a" := remove]
{}
A key/value pair used for building objects
String manipulation
match :: Expr string => ReQL -> string -> ReQLSource
Match a string to a regular expression.
>>>
run' h $ str "foobar" # match "f(.)+[bc](.+)"
{"groups":[{"start":2,"end":3,"str":"o"},{"start":4,"end":6,"str":"ar"}],"start":0,"end":6,"str":"foobar"}
downcase :: Expr str => str -> ReQLSource
Convert to lower case
>>>
run h $ downcase (str "Foo")
"foo"
split :: Expr str => str -> ReQLSource
Split a string on whitespace characters
>>>
run' h $ split (str "foo bar")
["foo","bar"]
splitOn :: Expr str => ReQL -> str -> ReQLSource
Split a string on a given delimiter
>>>
run' h $ str "foo, bar" # splitOn ","
["foo"," bar"]
>>>
run' h $ str "foo" # splitOn ""
["f","o","o"]
splitMax :: Expr str => ReQL -> ReQL -> str -> ReQLSource
Split a string up to a given number of times
>>>
run' h $ str "a:b:c:d" # splitMax ":" 2
["a","b","c:d"]
Math and logic
(+) :: (Expr a, Expr b) => a -> b -> ReQLSource
Addition or concatenation
Use the Num instance, or a qualified operator.
>>>
run h $ 2 + 5
7>>>
run h $ str "foo" R.+ str "bar"
"foobar"
(==) :: (Expr a, Expr b) => a -> b -> ReQLSource
Test for equality
>>>
run h $ ["a" := 1] R.== ["a" := 1]
true
(>=) :: (Expr a, Expr b) => a -> b -> ReQLSource
Greater than or equal to
>>>
run h $ [1] R.>= Null
false
A random float between 0 and 1
>>>
run' h $ (\x -> x R.< 1 R.&& x R.>= 0) `apply` [random]
true
randomTo :: ReQL -> ReQLSource
A random number between 0 and n
>>>
run' h $ (\x -> x R.< 10 R.&& x R.>= 0) `apply` [randomTo 10]
true
randomFromTo :: ReQL -> ReQL -> ReQLSource
A random number between 0 and n
>>>
run' h $ (\x -> x R.< 10 R.&& x R.>= 5) `apply` [randomFromTo 5 10]
true
Dates and times
time :: ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQL -> ReQLSource
Build a time object from the year, month, day, hour, minute, second and timezone fields
>>>
run' h $ time 2011 12 24 23 59 59 "Z"
Time<2011-12-24 23:59:59 +0000>
epochTime :: ReQL -> ReQLSource
Build a time object given the number of seconds since the unix epoch
>>>
run' h $ epochTime 1147162826
Time<2006-05-09 08:20:26 +0000>
Build a time object given an iso8601 string
>>>
run' h $ iso8601 "2012-01-07T08:34:00-0700"
Time<2012-01-07 08:34:00 -0700>
inTimezone :: Expr time => ReQL -> time -> ReQLSource
The same time in a different timezone
>>>
_ <- run' h $ inTimezone "+0800" now
during :: (Expr left, Expr right, Expr time) => Bound left -> Bound right -> time -> ReQLSource
Test if a time is between two other times
>>>
run' h $ during (Open $ now R.- (60*60)) (Closed now) $ epochTime 1382919271
false
toEpochTime :: Expr t => t -> ReQLSource
Convert a time to another representation
Control structures
apply :: (Expr fun, Expr arg) => fun -> [arg] -> ReQLSource
Apply a function to a list of arguments.
Called do in the official drivers
>>>
run h $ (\x -> x R.* 2) `apply` [4]
8
Evaluate a JavaScript expression
>>>
run' h $ js "Math.PI"
3.141592653589793>>>
let r_sin x = js "Math.sin" `apply` [x]
>>>
run h $ R.map r_sin [pi, pi/2]
[1.2246063538223773e-16,1]
branch :: (Expr a, Expr b, Expr c) => a -> b -> c -> ReQLSource
Server-side if
>>>
run h $ branch (1 R.< 2) 3 4
3
forEach :: (Expr s, Expr a) => s -> (ReQL -> a) -> ReQLSource
Like map but for write queries
>>>
_ <- run' h $ table "users" # replace (without ["post_count"])
>>>
run h $ forEach (table "users") (\user -> table "users" # get (user!"name") # ex update [nonAtomic] (const ["post_count" := R.count (table "posts" # R.filter (\post -> post!"author" R.== user!"name"))])) :: IO WriteResponse
{replaced:2}
error :: Expr s => s -> ReQLSource
Abort the query with an error
>>>
run' h $ R.error (str "haha") R./ 2 + 1
*** Exception: RethinkDB: Runtime error: "haha" in add(div({- HERE -} error("haha"), 2), 1)
handle :: (Expr instead, Expr reql) => (ReQL -> instead) -> reql -> ReQLSource
Catch some expections inside the query.
Called default in the official drivers
>>>
run h $ R.handle (const 0) $ ["a" := 1] ! "b"
0>>>
run h $ R.handle (expr . id) $ ["a" := 1] ! "b"
"No attribute `b` in object:\n{\n\t\"a\":\t1\n}"
Convert other types into ReQL expressions
Expr Bool | |
Expr Char | |
Expr Double | |
Expr Float | |
Expr Int | |
Expr Int8 | |
Expr Int16 | |
Expr Int32 | |
Expr Int64 | |
Expr Integer | |
Expr Word | |
Expr Word8 | |
Expr Word16 | |
Expr Word32 | |
Expr Word64 | |
Expr () | |
Expr ByteString | |
Expr ByteString | |
Expr Text | |
Expr UTCTime | |
Expr Value | |
Expr Text | |
Expr ZonedTime | |
Expr Datum | |
Expr Table | |
Expr Database | |
Expr ReQL | |
Expr Term | |
Expr Unit | |
Expr ConflictResolution | |
Expr Durability | |
Expr PaginationStrategy | |
Expr HttpMethod | |
Expr HttpResultFormat | |
Expr a => Expr [a] | |
Expr (Ratio Integer) | |
Expr a => Expr (Maybe a) | |
Expr a => Expr (Vector a) | |
Expr a => Expr (Set a) | |
Expr (Attribute a) | |
(~ * a ReQL, ~ * b ReQL) => Expr (a -> b -> ReQL) | |
~ * a ReQL => Expr (a -> ReQL) | |
(Expr a, Expr b) => Expr (Either a b) | |
(Expr a, Expr b) => Expr (a, b) | |
Expr a => Expr (HashMap [Char] a) | |
(Expr k, Expr v) => Expr (HashMap k v) | |
Expr a => Expr (HashMap Text a) | |
Expr a => Expr (Map [Char] a) | |
Expr a => Expr (Map Text a) | |
(Expr a, Expr b, Expr c) => Expr (a, b, c) | |
(Expr a, Expr b, Expr c, Expr d) => Expr (a, b, c, d) | |
(Expr a, Expr b, Expr c, Expr d, Expr e) => Expr (a, b, c, d, e) |
coerceTo :: Expr x => ReQL -> x -> ReQLSource
Convert a value to a different type
>>>
run h $ coerceTo "STRING" 1
"1"
asArray :: Expr x => x -> ReQLSource
Convert a value to an array
>>>
run h $ asArray $ ["a" := 1, "b" := 2] :: IO [(String, Int)]
[("a",1),("b",2)]
asString :: Expr x => x -> ReQLSource
Convert a value to a string
>>>
run h $ asString $ ["a" := 1, "b" := 2]
"{\n\t\"a\":\t1,\n\t\"b\":\t2\n}"
asObject :: Expr x => x -> ReQLSource
Convert a value to an object
>>>
run' h $ asObject $ [(str "a",1),("b",2)]
{"a":1,"b":2}
typeOf :: Expr a => a -> ReQLSource
A string representing the type of an expression
>>>
run h $ typeOf 1
"NUMBER"
info :: Expr a => a -> ReQLSource
Get information on a given expression. Useful for tables and databases.
>>>
run h $ info $ table "users"
{"primary_key":"name","name":"users","indexes":["friends","location"],"type":"TABLE","db":{"name":"doctests","type":"DB"}}
http :: Expr url => url -> HttpOptions -> ReQLSource
Retrieve data from the specified URL over HTTP
>>>
_ <- run' h $ http "http://httpbin.org/get" def{ httpParams = Just ["foo" := 1] }
>>>
_ <- run' h $ http "http://httpbin.org/put" def{ httpMethod = Just PUT, httpData = Just $ expr ["foo" := "bar"] }
data HttpOptions Source
HttpOptions | |
|
Geospatial commands
circle :: (Expr point, Expr radius) => point -> radius -> ReQLSource
Create a polygon approximating a circle
>>>
run' h $ ex circle [numVertices 6, unit Kilometer] (point (-73) 40) 100
Polygon<[[-73,39.099310036015424],[-74.00751390838496,39.54527799206398],[-74.02083610406069,40.445812561599965],[-73,40.900549591978255],[-71.97916389593931,40.445812561599965],[-71.99248609161504,39.54527799206398],[-73,39.099310036015424]]>
distance :: (Expr a, Expr b) => a -> b -> ReQLSource
Distance between a point and another geometry object
>>>
run' h $ distance (point (-73) 40) (point (-122) 37)
4233453.467303547>>>
run' h $ ex distance [unit Mile] (point (-73) 40) (point (-122) 37)
2630.54602825968
fill :: Expr line => line -> ReQLSource
Convert a line object into a polygon
>>>
run' h $ fill $ line [[-122,37], [-120,39], [-121,38]]
Polygon<[[-122,37],[-120,39],[-121,38],[-122,37]]>
geoJSON :: Expr geojson => geojson -> ReQLSource
Convert a GeoJSON object into a RethinkDB geometry object
>>>
run' h $ geoJSON ["type" := "Point", "coordinates" := [-45,80]]
Point<[-45,80]>
toGeoJSON :: Expr geo => geo -> ReQLSource
Convert a RethinkDB geometry object into a GeoJSON object
>>>
run' h $ toGeoJSON $ point (-122.423246) 37.779388
{"coordinates":[-122.423246,37.779388],"type":"Point"}
getIntersecting :: (Expr geo, Expr table) => geo -> Index -> table -> ReQLSource
Search a geospatial index for intersecting objects
>>>
run' h $ table "places" # getIntersecting (point (-122) 37) (Index "geo")
[]
getNearest :: (Expr point, Expr table) => point -> Index -> table -> ReQLSource
Query a geospatial index for the nearest matches
>>>
run' h $ table "places" # getNearest (point (-122) 37) (Index "location")
[]>>>
run' h $ table "places" # ex getNearest [maxResults 5, maxDist 10, unit Kilometer] (point (-122) 37) (Index "location")
[]
includes :: (Expr area, Expr geo) => geo -> area -> ReQLSource
Test whether a geometry object includes another
>>>
run' h $ circle (point (-122) 37) 5000 # includes (point (-120) 48)
false
intersects :: (Expr a, Expr b) => a -> b -> ReQLSource
Test if two geometry objects intersects
>>>
run' h $ intersects (line [[-122,37],[-120,48]]) (line [[-120,49],[-122,48]])
false
line :: Expr points => points -> ReQLSource
Create a line object
>>>
run' h $ line [[-73,45],[-122,37]]
Line<[-73,45],[-122,37]>
point :: (Expr longitude, Expr latitude) => longitude -> latitude -> ReQLSource
Create a point objects
>>>
run' h $ point (-73) 40
Point<[-73,40]>
polygon :: Expr points => points -> ReQLSource
Create a polygon object
>>>
run' h $ polygon [[-73,45],[-122,37],[-73,40]]
Polygon<[[-73,45],[-122,37],[-73,40],[-73,45]]>
polygonSub :: (Expr polygon, Expr hole) => hole -> polygon -> ReQLSource
Punch a hole in a polygon
>>>
run' h $ (polygon [[-73,45],[-122,37],[-73,40]]) # polygonSub (polygon [[-73.2,40.1],[-73.2,40.2],[-73.3,40.1]])
Polygon<[[-73,45],[-122,37],[-73,40],[-73,45]],[[-73.2,40.1],[-73.2,40.2],[-73.3,40.1],[-73.2,40.1]]>
maxResults :: ReQL -> Attribute aSource
Optional argument for getNearest
numVertices :: ReQL -> Attribute aSource
Optional argument for circle
Helpers
A shortcut for inserting strings into ReQL expressions Useful when OverloadedStrings makes the type ambiguous