{-|
Module: Squeal.PostgreSQL.Expression.TextSearch
Description: text search functions and operators
Copyright: (c) Eitan Chatav, 2019
Maintainer: eitan@morphism.tech
Stability: experimental

text search functions and operators
-}

{-# LANGUAGE
    DataKinds
  , OverloadedStrings
  , TypeOperators
#-}

module Squeal.PostgreSQL.Expression.TextSearch
  ( -- * Text Search Operator
    (@@)
  , (.&)
  , (.|)
  , (.!)
  , (<->)
    -- * Text Search Function
  , arrayToTSvector
  , tsvectorLength
  , numnode
  , plainToTSquery
  , phraseToTSquery
  , websearchToTSquery
  , queryTree
  , toTSquery
  , toTSvector
  , setWeight
  , strip
  , jsonToTSvector
  , jsonbToTSvector
  , tsDelete
  , tsFilter
  , tsHeadline
  ) where

import Squeal.PostgreSQL.Expression
import Squeal.PostgreSQL.Type.List
import Squeal.PostgreSQL.Type.Schema

-- | `Squeal.PostgreSQL.Expression.Type.tsvector` matches tsquery ?
(@@) :: Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
@@ :: forall (null :: PGType -> NullType).
Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
(@@) = forall (ty0 :: NullType) (ty1 :: NullType) (ty2 :: NullType).
ByteString -> Operator ty0 ty1 ty2
unsafeBinaryOp ByteString
"@@"

-- | AND `Squeal.PostgreSQL.Expression.Type.tsquery`s together
(.&) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
.& :: forall (null :: PGType -> NullType).
Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
(.&) = forall (ty0 :: NullType) (ty1 :: NullType) (ty2 :: NullType).
ByteString -> Operator ty0 ty1 ty2
unsafeBinaryOp ByteString
"&&"

-- | OR `Squeal.PostgreSQL.Expression.Type.tsquery`s together
(.|) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
.| :: forall (null :: PGType -> NullType).
Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
(.|) = forall (ty0 :: NullType) (ty1 :: NullType) (ty2 :: NullType).
ByteString -> Operator ty0 ty1 ty2
unsafeBinaryOp ByteString
"||"

-- | negate a `Squeal.PostgreSQL.Expression.Type.tsquery`
(.!) :: null 'PGtsquery --> null 'PGtsquery
.! :: forall (null :: PGType -> NullType).
null 'PGtsquery --> null 'PGtsquery
(.!) = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeLeftOp ByteString
"!!"

-- | `Squeal.PostgreSQL.Expression.Type.tsquery` followed by
-- `Squeal.PostgreSQL.Expression.Type.tsquery`
(<->) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
<-> :: forall (null :: PGType -> NullType).
Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
(<->) = forall (ty0 :: NullType) (ty1 :: NullType) (ty2 :: NullType).
ByteString -> Operator ty0 ty1 ty2
unsafeBinaryOp ByteString
"<->"

-- | convert array of lexemes to `Squeal.PostgreSQL.Expression.Type.tsvector`
arrayToTSvector
  ::   null ('PGvararray ('NotNull 'PGtext))
  --> null 'PGtsvector
arrayToTSvector :: forall (null :: PGType -> NullType).
null ('PGvararray ('NotNull 'PGtext)) --> null 'PGtsvector
arrayToTSvector = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"array_to_tsvector"

-- | number of lexemes in `Squeal.PostgreSQL.Expression.Type.tsvector`
tsvectorLength :: null 'PGtsvector --> null 'PGint4
tsvectorLength :: forall (null :: PGType -> NullType).
null 'PGtsvector --> null 'PGint4
tsvectorLength = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"length"

-- | number of lexemes plus operators in `Squeal.PostgreSQL.Expression.Type.tsquery`
numnode :: null 'PGtsquery --> null 'PGint4
numnode :: forall (null :: PGType -> NullType).
null 'PGtsquery --> null 'PGint4
numnode = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"numnode"

-- | produce `Squeal.PostgreSQL.Expression.Type.tsquery` ignoring punctuation
plainToTSquery :: null 'PGtext --> null 'PGtsquery
plainToTSquery :: forall (null :: PGType -> NullType).
null 'PGtext --> null 'PGtsquery
plainToTSquery = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"plainto_tsquery"

-- | produce `Squeal.PostgreSQL.Expression.Type.tsquery` that searches for a phrase,
-- ignoring punctuation
phraseToTSquery :: null 'PGtext --> null 'PGtsquery
phraseToTSquery :: forall (null :: PGType -> NullType).
null 'PGtext --> null 'PGtsquery
phraseToTSquery = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"phraseto_tsquery"

-- | produce `Squeal.PostgreSQL.Expression.Type.tsquery` from a web search style query
websearchToTSquery :: null 'PGtext --> null 'PGtsquery
websearchToTSquery :: forall (null :: PGType -> NullType).
null 'PGtext --> null 'PGtsquery
websearchToTSquery = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"websearch_to_tsquery"

-- | get indexable part of a `Squeal.PostgreSQL.Expression.Type.tsquery`
queryTree :: null 'PGtsquery --> null 'PGtext
queryTree :: forall (null :: PGType -> NullType).
null 'PGtsquery --> null 'PGtext
queryTree = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"query_tree"

-- | normalize words and convert to `Squeal.PostgreSQL.Expression.Type.tsquery`
toTSquery :: null 'PGtext --> null 'PGtsquery
toTSquery :: forall (null :: PGType -> NullType).
null 'PGtext --> null 'PGtsquery
toTSquery = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"to_tsquery"

-- | reduce document text to `Squeal.PostgreSQL.Expression.Type.tsvector`
toTSvector
  :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
  => null ty --> null 'PGtsvector
toTSvector :: forall (ty :: PGType) (null :: PGType -> NullType).
In ty '[ 'PGtext, 'PGjson, 'PGjsonb] =>
null ty --> null 'PGtsvector
toTSvector = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"to_tsvector"

-- | assign weight to each element of `Squeal.PostgreSQL.Expression.Type.tsvector`
setWeight :: '[null 'PGtsvector, null ('PGchar 1)] ---> null 'PGtsvector
setWeight :: forall (null :: PGType -> NullType).
'[null 'PGtsvector, null ('PGchar 1)] ---> null 'PGtsvector
setWeight = forall (xs :: [NullType]) (y :: NullType).
SListI xs =>
ByteString -> xs ---> y
unsafeFunctionN ByteString
"set_weight"

-- | remove positions and weights from `Squeal.PostgreSQL.Expression.Type.tsvector`
strip :: null 'PGtsvector --> null 'PGtsvector
strip :: forall (null :: PGType -> NullType).
null 'PGtsvector --> null 'PGtsvector
strip = forall (x :: NullType) (y :: NullType). ByteString -> x --> y
unsafeFunction ByteString
"strip"

-- | @jsonToTSvector (document *: filter)@
-- reduce each value in the document, specified by filter to a `Squeal.PostgreSQL.Expression.Type.tsvector`,
-- and then concatenate those in document order to produce a single `Squeal.PostgreSQL.Expression.Type.tsvector`.
-- filter is a `Squeal.PostgreSQL.Expression.Type.json` array, that enumerates what kind of elements
-- need to be included into the resulting `Squeal.PostgreSQL.Expression.Type.tsvector`.
-- Possible values for filter are "string" (to include all string values),
-- "numeric" (to include all numeric values in the string format),
-- "boolean" (to include all Boolean values in the string format "true"/"false"),
-- "key" (to include all keys) or "all" (to include all above).
-- These values can be combined together to include, e.g. all string and numeric values.
jsonToTSvector :: '[null 'PGjson, null 'PGjson] ---> null 'PGtsvector
jsonToTSvector :: forall (null :: PGType -> NullType).
'[null 'PGjson, null 'PGjson] ---> null 'PGtsvector
jsonToTSvector = forall (xs :: [NullType]) (y :: NullType).
SListI xs =>
ByteString -> xs ---> y
unsafeFunctionN ByteString
"json_to_tsvector"

-- | @jsonbToTSvector (document *: filter)@
-- reduce each value in the document, specified by filter to a `Squeal.PostgreSQL.Expression.Type.tsvector`,
-- and then concatenate those in document order to produce a single `Squeal.PostgreSQL.Expression.Type.tsvector`.
-- filter is a `Squeal.PostgreSQL.Expression.Type.jsonb` array, that enumerates what kind of elements
-- need to be included into the resulting `Squeal.PostgreSQL.Expression.Type.tsvector`.
-- Possible values for filter are "string" (to include all string values),
-- "numeric" (to include all numeric values in the string format),
-- "boolean" (to include all Boolean values in the string format "true"/"false"),
-- "key" (to include all keys) or "all" (to include all above).
-- These values can be combined together to include, e.g. all string and numeric values.
jsonbToTSvector :: '[null 'PGjsonb, null 'PGjsonb] ---> null 'PGtsvector
jsonbToTSvector :: forall (null :: PGType -> NullType).
'[null 'PGjsonb, null 'PGjsonb] ---> null 'PGtsvector
jsonbToTSvector = forall (xs :: [NullType]) (y :: NullType).
SListI xs =>
ByteString -> xs ---> y
unsafeFunctionN ByteString
"jsonb_to_tsvector"

-- | remove given lexeme from `Squeal.PostgreSQL.Expression.Type.tsvector`
tsDelete ::
  '[null 'PGtsvector, null ('PGvararray ('NotNull 'PGtext))]
   ---> null 'PGtsvector
tsDelete :: forall (null :: PGType -> NullType).
'[null 'PGtsvector, null ('PGvararray ('NotNull 'PGtext))]
---> null 'PGtsvector
tsDelete = forall (xs :: [NullType]) (y :: NullType).
SListI xs =>
ByteString -> xs ---> y
unsafeFunctionN ByteString
"ts_delete"

-- | select only elements with given weights from `Squeal.PostgreSQL.Expression.Type.tsvector`
tsFilter ::
  '[null 'PGtsvector, null ('PGvararray ('NotNull ('PGchar 1)))]
   ---> null 'PGtsvector
tsFilter :: forall (null :: PGType -> NullType).
'[null 'PGtsvector, null ('PGvararray ('NotNull ('PGchar 1)))]
---> null 'PGtsvector
tsFilter = forall (xs :: [NullType]) (y :: NullType).
SListI xs =>
ByteString -> xs ---> y
unsafeFunctionN ByteString
"ts_filter"

-- | display a `Squeal.PostgreSQL.Expression.Type.tsquery` match
tsHeadline
  :: document `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
  => '[null document, null 'PGtsquery] ---> null 'PGtext
tsHeadline :: forall (document :: PGType) (null :: PGType -> NullType).
In document '[ 'PGtext, 'PGjson, 'PGjsonb] =>
'[null document, null 'PGtsquery] ---> null 'PGtext
tsHeadline = forall (xs :: [NullType]) (y :: NullType).
SListI xs =>
ByteString -> xs ---> y
unsafeFunctionN ByteString
"ts_headline"