sphinx 0.5.3.1 → 0.6.0
raw patch · 9 files changed
+208/−103 lines, 9 filesdep +textdep +text-icudep −utf8-string
Dependencies added: text, text-icu
Dependencies removed: utf8-string
Files
- README.md +51/−13
- Text/Search/Sphinx.hs +85/−66
- Text/Search/Sphinx/Configuration.hs +19/−1
- Text/Search/Sphinx/ExcerptConfiguration.hs +3/−0
- Text/Search/Sphinx/Get.hs +20/−11
- Text/Search/Sphinx/Indexable.hs +2/−2
- Text/Search/Sphinx/Put.hs +9/−0
- Text/Search/Sphinx/Types.hs +15/−7
- sphinx.cabal +4/−3
README.md view
@@ -6,30 +6,53 @@ # Usage -`query` executes a single query.-`runQueries` executes multiple queries at once that were created them with `addQuery`+## Constructing Queries -In extended mode you may want to escape special query characters with `escapeString`+The data type `Query` is used to represent queries to the server. It specifies+a search string and the indexes to run the query on, as well as a comment,+which may be the empty string. In order to run a query on all indexes, use+`"*"` in the index field. -`buildExcerpts` creates highlighted excerpts+The convenience function `query` executes a single query and constructs the+`Query` by itself, so you don't have to. -You will probably need to import the types also:+To execute more than one `Query`, use `runQueries`. Details are below in the+section [*Batch Queries*](#batch-queries). To construct simple queries, you can+also use `simpleQuery :: Text -> Query` which constructs a `Query` over all+indexes. Don't forget that you can use record updates on a `Query`. +In extended mode you may want to escape special query characters with `escapeString`.++All interaction with the server, including sending queries and receiving+results, is based on the `Data.Text` string type. You might therefore want to+enable the `OverloadedStrings` pragma.++## Excerpts and XML Indexes++`buildExcerpts` creates highlighted excerpts.++You will probably need to import the types as well:+ import qualified Text.Search.Sphinx as Sphinx import qualified Text.Search.Sphinx.Types as SphinxT -There is also an `Indexable` module for generating an xml file of data to be indexed+There is also an `Indexable` module for generating an xml file of data to be indexed. -## runQueries helpers+## Batch Queries -`runQueries` pipelines multiple queries together. If you are trying to combine the results, there are some helpers such as `maybeQueries` and `resultsToMatches`+You can send more than one query per request to the server (which may enable+server-side query optimization in certain cases. Refer to the+[Sphinx manual](http://sphinxsearch.com/docs/2.0.4/api-func-addquery.html)+for details.) The function `runQueries` pipelines multiple queries together. If you+are trying to combine the results, there are some helpers such as+`maybeQueries` and `resultsToMatches`. ~~~~~~ {.haskell} mr <- Sphinx.maybeQueries sphinxLogger sphinxConfig [- addQuery "db1" query1- , addQuery "db2" query1- , addQuery "db1" query2- , addQuery "db2" query2+ SphinxT.Query query1 "db1" ""+ , SphinxT.Query query1 "db2" ""+ , SphinxT.Query query2 "db1" ""+ , SphinxT.Query query2 "db2" "" ] case mr of Nothing -> return Nothing@@ -40,9 +63,24 @@ else return $ Just combined ~~~~~~ +**A note** for those transitioning from `0.5.*` to `0.6`: the function `addQueries`+has been removed. You can now directly send a list of `Query` to the server by using+`runQueries`, which will handle the serialization for you behind the scenes. +## Encoding +The sphinx server itself does not know about encodings except for the+difference between single-byte encodings and multi-byte encodings. It assumes+that all incoming queries are already properly encoded and matches the raw+bytes it receives; the same holds for the results returned by the server. Hence+the responsibilty for using the proper encoding (and decoding) routines lies+with the caller. +Version 0.6.0 of `haskell-sphinx-client` introduces the `encoding` field in+both the `Configuration` data type and the `ExcerptConfiguration` data type.+The library handles proper encoding and decoding in the background; just+make sure you set the right encoding setting in the configuration!+ Details ======= @@ -59,4 +97,4 @@ Usage of this haskell client ---------------------------- Tupil originally wrote this for use on a commercial project.-This sphinx package is now finding some use in the Yesod community. [Here is a well described example usage](http://www.yesodweb.com/book/sphinx), but do keep in mind there is no requirement to tie the *generation* of sphinx documents to your web application, just your database. Used in Yesod applications yesdoweb.com and eatnutrients.com.+This sphinx package is now finding some use in the Yesod community. [Here is a well described example usage](https://github.com/yesodweb/yesod/wiki/Sphinx-Search), but do keep in mind there is no requirement to tie the *generation* of sphinx documents to your web application, just your database. Used in Yesod applications yesdoweb.com and eatnutrients.com.
Text/Search/Sphinx.hs view
@@ -5,13 +5,22 @@ -- setFilterFloatRange, setGeoAnchor -- resetFilters, resetGroupBy -- updateAttributes,--- buildKeyWords, escapeString, status, open, close-module Text.Search.Sphinx ( module Text.Search.Sphinx+-- buildKeyWords, status, open, close+module Text.Search.Sphinx + ( escapeText+ , query+ , buildExcerpts+ , runQueries+ , runQueries'+ , resultsToMatches+ , maybeQueries+ , T.Query(..), simpleQuery , Configuration(..), defaultConfig ) where import qualified Text.Search.Sphinx.Types as T ( Match,+ Query(..), VerCommand(VcSearch, VcExcerpt), SearchdCommand(ScSearch, ScExcerpt), Filter, Filter(..),@@ -21,9 +30,9 @@ import Text.Search.Sphinx.Configuration (Configuration(..), defaultConfig) import qualified Text.Search.Sphinx.ExcerptConfiguration as ExConf (ExcerptConfiguration(..))-import Text.Search.Sphinx.Get (times, getResult, readHeader, getStr)+import Text.Search.Sphinx.Get (times, getResult, readHeader, getStr, getTxt) import Text.Search.Sphinx.Put (num, num64, enum, list, numC, strC, foldPuts,- numC64, stringIntList, str, cmd, verCmd)+ numC64, stringIntList, str, txt, cmd, verCmd) import Data.Binary.Put (Put, runPut) import Data.Binary.Get (runGet, getWord32be)@@ -38,6 +47,10 @@ import Prelude hiding (filter, tail) import Data.List (nub) +import Data.Text (Text)+import qualified Data.Text as X+import qualified Data.Text.ICU.Convert as ICU+ {- the funnest way to debug this is to run the same query with an existing working client and look at the difference - sudo tcpflow -i lo dst port 9306 import Debug.Trace; debug a = trace (show a) a@@ -46,23 +59,22 @@ escapedChars :: String escapedChars = '"':'\\':"-!@~/()*[]=" --- | escape all possible meta characters.--- most of these characters only need to be escaped in certain contexts+-- | Escape all possible meta characters.+-- Most of these characters only need to be escaped in certain contexts -- however, in normal searching they will all be ignored-escapeString :: String -> String-escapeString [] = []-escapeString (x:xs) = if x `elem` escapedChars- then '\\':x:escapeString xs- else x:escapeString xs+escapeText :: Text -> Text+escapeText = X.intercalate "\\" . breakBy (`elem` escapedChars)+ where breakBy p t | X.null t = [X.empty]+ | otherwise = (if p $ X.head t then ("":) else id) $ X.groupBy (\_ x -> not $ p x) t -- | The 'query' function runs a single query against the Sphinx daemon.--- To pipeline multiple queries in a batch, use addQuery and runQueries+-- To pipeline multiple queries in a batch, use and 'runQueries'. query :: Configuration -- ^ The configuration- -> String -- ^ The indexes, "*" means every index- -> String -- ^ The query string+ -> Text -- ^ The indexes, \"*\" means every index+ -> Text -- ^ The query string -> IO (T.Result T.QueryResult) -- ^ just one search result back query config indexes search = do- let q = addQuery config search indexes ""+ let q = T.Query search indexes X.empty results <- runQueries' config [q] -- same as toSearchResult, but we know there is just one query -- could just remove and use runQueries in the future@@ -75,9 +87,16 @@ T.Retry retry -> T.Retry retry T.Warning warning (result:results) -> case result of T.QueryOk result -> T.Warning warning result- T.QueryWarning w result -> T.Warning (BS.append warning w) result+ T.QueryWarning w result -> T.Warning (X.append warning w) result T.QueryError code e -> T.Error code e +-- | This is a convenience function which accepts a search string and+-- builds a query for that string over all indexes without attaching+-- comments to the queries.+simpleQuery :: Text -- ^ The query string+ -> T.Query -- ^ A query value that can be sent to 'runQueries'+simpleQuery q = T.Query q "*" X.empty+ connect :: String -> Int -> IO Handle connect host port = do connection <- connectTo host (PortNumber $ fromIntegral $ port)@@ -89,24 +108,25 @@ -- | TODO: add configuration options buildExcerpts :: ExConf.ExcerptConfiguration -- ^ Contains host and port for connection and optional configuration for buildExcerpts- -> [String] -- ^ list of document contents to be highlighted- -> String -- ^ The indexes, "*" means every index- -> String -- ^ The query string to use for excerpts- -> IO (T.Result [BS.ByteString]) -- ^ the documents with excerpts highlighted+ -> [Text] -- ^ list of document contents to be highlighted+ -> Text -- ^ The indexes, \"*\" means every index+ -> Text -- ^ The query string to use for excerpts+ -> IO (T.Result [Text]) -- ^ the documents with excerpts highlighted buildExcerpts config docs indexes words = do conn <- connect (ExConf.host config) (ExConf.port config)- let req = runPut $ makeBuildExcerpt addExcerpt+ conv <- ICU.open (ExConf.encoding config) Nothing+ let req = runPut $ makeBuildExcerpt (addExcerpt conv) BS.hPut conn req hFlush conn (status, response) <- getResponse conn case status of- T.OK -> return $ T.Ok (getResults response)- T.WARNING -> return $ T.Warning (runGet getStr response) (getResults response)- T.RETRY -> return $ T.Retry (errorMessage response)- T.ERROR n -> return $ T.Error n (errorMessage response)+ T.OK -> return $ T.Ok (getResults response conv)+ T.WARNING -> return $ T.Warning (runGet (getTxt conv) response) (getResults response conv)+ T.RETRY -> return $ T.Retry (errorMessage conv response)+ T.ERROR n -> return $ T.Error n (errorMessage conv response) where- getResults response = runGet ((length docs) `times` getStr) response- errorMessage response = BS.tail (BS.tail (BS.tail (BS.tail response)))+ getResults response conv = runGet ((length docs) `times` getTxt conv) response+ errorMessage conv response = runGet (getTxt conv) (BS.drop 4 response) makeBuildExcerpt putExcerpt = do cmd T.ScExcerpt@@ -114,19 +134,19 @@ num $ fromEnum $ BS.length (runPut putExcerpt) putExcerpt - addExcerpt :: Put- addExcerpt = do+ addExcerpt :: ICU.Converter -> Put+ addExcerpt conv = do num 0 -- mode num $ excerptFlags config- str indexes- str words+ txt conv indexes+ txt conv words strC config [ExConf.beforeMatch, ExConf.afterMatch, ExConf.chunkSeparator] numC config [ExConf.limit, ExConf.around, ExConf.limitPassages, ExConf.limitWords, ExConf.startPassageId] str $ ExConf.htmlStripMode config #ifndef ONE_ONE_BETA str $ ExConf.passageBoundary config #endif- list str docs+ list (txt conv) docs modeFlag :: ExConf.ExcerptConfiguration -> (ExConf.ExcerptConfiguration -> Bool) -> Int -> Int modeFlag cfg setting value = if setting cfg then value else 0@@ -144,10 +164,10 @@ ]) --- | Use with addQuery to pipeline multiple queries.+-- | Make multiple queries at once, using a list of 'T.Query'. -- For a single query, just use the query method -- Easier handling of query result than runQueries'-runQueries :: Configuration -> [Put] -> IO (T.Result [T.QueryResult])+runQueries :: Configuration -> [T.Query] -> IO (T.Result [T.QueryResult]) runQueries cfg qs = runQueries' cfg qs >>= return . toSearchResult where -- with batched queries, each query can have an error code,@@ -161,39 +181,39 @@ toSearchResult :: T.Result [T.SingleResult] -> T.Result [T.QueryResult] toSearchResult results = case results of- T.Ok rs -> fromOk rs [] BS.empty+ T.Ok rs -> fromOk rs [] X.empty T.Warning warning rs -> fromWarn warning rs [] T.Retry retry -> T.Retry retry T.Error code error -> T.Error code error where- fromOk :: [T.SingleResult] -> [T.QueryResult] -> BS.ByteString -> T.Result [T.QueryResult]- fromOk [] acc warn | BS.null warn = T.Ok acc+ fromOk :: [T.SingleResult] -> [T.QueryResult] -> Text -> T.Result [T.QueryResult]+ fromOk [] acc warn | X.null warn = T.Ok acc | otherwise = T.Warning warn acc fromOk (r:rs) acc warn = case r of T.QueryOk result -> fromOk rs (acc ++ [result]) warn- T.QueryWarning w result -> fromOk rs (acc ++ [result]) (BS.append warn w)+ T.QueryWarning w result -> fromOk rs (acc ++ [result]) (X.append warn w) T.QueryError code e -> T.Error code e - fromWarn :: BS.ByteString -> [T.SingleResult] -> [T.QueryResult] -> T.Result [T.QueryResult]+ fromWarn :: Text -> [T.SingleResult] -> [T.QueryResult] -> T.Result [T.QueryResult] fromWarn warning [] acc = T.Warning warning acc fromWarn warning (r:rs) acc = case r of T.QueryOk result -> fromWarn warning rs (result:acc)- T.QueryWarning w result -> fromWarn (BS.append warning w) rs (result:acc)+ T.QueryWarning w result -> fromWarn (X.append warning w) rs (result:acc) T.QueryError code e -> T.Error code e --- | lower level- called by 'runQueries'--- | This may be useful for debugging problems- warning messages won't get compressed-runQueries' :: Configuration -> [Put] -> IO (T.Result [T.SingleResult])+-- | Lower level- called by 'runQueries'.+-- This may be useful for debugging problems- warning messages won't get compressed+runQueries' :: Configuration -> [T.Query] -> IO (T.Result [T.SingleResult]) runQueries' config qs = do conn <- connect (host config) (port config)- BS.hPut conn request+ conv <- ICU.open (encoding config) Nothing+ let queryReq = foldPuts $ map (serializeQuery config conv) qs+ BS.hPut conn (request queryReq) hFlush conn- getSearchResult conn+ getSearchResult conn conv where numQueries = length qs- queryReq = foldPuts qs-- request = runPut $ do+ request qr = runPut $ do cmd T.ScSearch verCmd T.VcSearch num $ @@ -202,24 +222,24 @@ #else 8 #endif- + (fromEnum $ BS.length (runPut queryReq))+ + (fromEnum $ BS.length (runPut qr)) #ifndef ONE_ONE_BETA num 0 #endif num numQueries- queryReq+ qr - getSearchResult :: Handle -> IO (T.Result [T.SingleResult])- getSearchResult conn = do+ getSearchResult :: Handle -> ICU.Converter -> IO (T.Result [T.SingleResult])+ getSearchResult conn conv = do (status, response) <- getResponse conn case status of- T.OK -> return $ T.Ok (getResults response)- T.WARNING -> return $ T.Warning (runGet getStr response) (getResults response)- T.RETRY -> return $ T.Retry (errorMessage response)- T.ERROR n -> return $ T.Error n (errorMessage response)+ T.OK -> return $ T.Ok (getResults response conv)+ T.WARNING -> return $ T.Warning (runGet (getTxt conv) response) (getResults response conv)+ T.RETRY -> return $ T.Retry (errorMessage conv response)+ T.ERROR n -> return $ T.Error n (errorMessage conv response) where- getResults response = runGet (numQueries `times` getResult) response- errorMessage response = BS.tail (BS.tail (BS.tail (BS.tail response)))+ getResults response conv = runGet (numQueries `times` getResult conv) response+ errorMessage conv response = runGet (getTxt conv) (BS.drop 4 response) -- | Combine results from 'runQueries' into matches.@@ -237,7 +257,7 @@ -- | executes 'runQueries'. Log warning and errors, automatically retry. -- Return a Nothing on error, otherwise a Just.-maybeQueries :: (BS.ByteString -> IO ()) -> Configuration -> [Put] -> IO (Maybe [T.QueryResult])+maybeQueries :: (Text -> IO ()) -> Configuration -> [T.Query] -> IO (Maybe [T.QueryResult]) maybeQueries logCallback conf queries = do result <- runQueries conf queries case result of@@ -245,9 +265,8 @@ T.Retry msg -> logCallback msg >> maybeQueries logCallback conf queries T.Warning w r -> logCallback w >> return (Just r) T.Error code msg ->- logCallback (BS.concat ["Error code ",BS8.pack $ show code,". ",msg]) >> return Nothing+ logCallback (X.concat ["Error code ",X.pack $ show code,". ",msg]) >> return Nothing --- | TODO: hide this function getResponse :: Handle -> IO (T.Status, BS.ByteString) getResponse conn = do header <- BS.hGet conn 8@@ -259,17 +278,17 @@ return (status, response) -- | use with runQueries to pipeline a batch of queries-addQuery :: Configuration -> String -> String -> String -> Put-addQuery cfg query indexes comment = do+serializeQuery :: Configuration -> ICU.Converter -> T.Query -> Put+serializeQuery cfg conv (T.Query qry indexes comment) = do numC cfg [ offset , limit , fromEnum . mode , fromEnum . ranker , fromEnum . sort] str (sortBy cfg)- str query+ txt conv qry list num (weights cfg)- str indexes+ txt conv indexes num 1 -- id64 range marker numC64 cfg [minId, maxId] -- id64 range @@ -287,7 +306,7 @@ stringIntList (indexWeights cfg) num (maxQueryTime cfg) stringIntList (fieldWeights cfg)- str comment+ txt conv comment num 0 -- attribute overrides (none) str (selectClause cfg) -- select-list where
Text/Search/Sphinx/Configuration.hs view
@@ -3,11 +3,28 @@ import qualified Text.Search.Sphinx.Types as T -- | The configuration for a query+--+-- A note about encodings: The encoding specified here is used to encode+-- every @Text@ value that is sent to the server, and it used to decode all+-- of the server's answers, including error messages.+--+-- If the specified encoding doesn't support characters sent to the server,+-- they will silently be substituted with the byte value of @\'\\SUB\' ::+-- 'Char'@ before transmission.+--+-- If the server sends a byte value back that the encoding doesn't understand,+-- the affected bytes will be converted into special values as+-- specified by that encoding. For example, when decoding invalid UTF-8,+-- all invalid bytes are going to be substituted with @\'\\65533\' ::+-- 'Char'@.+-- data Configuration = Configuration { -- | The hostname of the Sphinx daemon host :: String -- | The portnumber of the Sphinx daemon , port :: Int+ -- | Encoding used to encode queries to the server, and decode server responses+ , encoding :: String -- | Per-field weights , weights :: [Int] -- | How many records to seek from result-set start (default is 0)@@ -50,7 +67,7 @@ , maxQueryTime :: Int -- | Per-field-name weights , fieldWeights :: [(String, Int)]- -- | attributes to select, defaults to '*'+ -- | attributes to select, defaults to \"*\" , selectClause :: String -- setSelect in regular API } deriving (Show)@@ -59,6 +76,7 @@ defaultConfig = Configuration { port = 3312 , host = "127.0.0.1"+ , encoding = "UTF-8" , weights = [] , offset = 0 , limit = 20
Text/Search/Sphinx/ExcerptConfiguration.hs view
@@ -7,6 +7,8 @@ host :: String -- | The portnumber of the Sphinx daemon , port :: Int+ -- | Encoding used to encode queries to the server, and decode server responses+ , encoding :: String , beforeMatch :: String , afterMatch :: String , chunkSeparator :: String@@ -33,6 +35,7 @@ defaultConfig = ExcerptConfiguration { port = 3312 , host = "127.0.0.1"+ , encoding = "utf8" , beforeMatch = "<b>" , afterMatch = "</b>" , chunkSeparator = "..."
Text/Search/Sphinx/Get.hs view
@@ -10,6 +10,8 @@ import qualified Text.Search.Sphinx.Types as T import Data.Maybe (isJust, fromJust) +import qualified Data.Text.ICU.Convert as ICU+ -- Utility functions getNum :: Get Int getNum = getWord32be >>= return . fromEnum@@ -24,17 +26,23 @@ num `times` f times = replicateM +getTxt conv = liftM (ICU.toUnicode conv) getStrStr+ getStr = do len <- getNum getLazyByteString (fromIntegral len) -getResult :: Get (T.SingleResult)-getResult = do+-- Get a strict 'ByteString'.+getStrStr = do len <- getNum+ getByteString (fromIntegral len)++getResult :: ICU.Converter -> Get (T.SingleResult)+getResult conv = do statusNum <- getNum case T.toQueryStatus statusNum of- T.QueryERROR n -> do e <- getStr+ T.QueryERROR n -> do e <- getTxt conv return $ T.QueryError statusNum e T.QueryOK -> getResultOk >>= return . T.QueryOk- T.QueryWARNING -> do w <- getStr+ T.QueryWARNING -> do w <- getTxt conv getResultOk >>= return . (T.QueryWarning w) where getResultOk = do@@ -42,17 +50,18 @@ attrs <- readList readAttrPair matchCount <- getNum id64 <- getNum- matches <- matchCount `times` readMatch (id64 > 0) (map snd attrs)+ matches <- matchCount `times` readMatch (id64 > 0) (map snd attrs) conv [total, totalFound, time, numWords] <- 4 `times` getNum- wrds <- numWords `times` readWord+ wrds <- numWords `times` readWord conv return $ T.QueryResult matches total totalFound wrds (map fst attrs) -readWord = do s <- getStr- [doc, hits] <- 2 `times` getNum- return (s, doc, hits)+readWord conv = do+ s <- getStrStr+ [doc, hits] <- 2 `times` getNum+ return (ICU.toUnicode conv s, doc, hits) -readMatch isId64 attrs = do+readMatch isId64 attrs conv = do doc <- if isId64 then getNum64 else (getNum >>= return . fromIntegral) weight <- getNum matchAttrs <- mapM readAttr attrs@@ -60,7 +69,7 @@ where readAttr (T.AttrTMulti attr) = (readList (readAttr attr)) >>= return . T.AttrMulti readAttr T.AttrTBigInt = getNum64 >>= return . T.AttrBigInt- readAttr T.AttrTString = getStr >>= return . T.AttrString+ readAttr T.AttrTString = getStrStr >>= return . T.AttrString . ICU.toUnicode conv readAttr T.AttrTUInt = getNum >>= return . T.AttrUInt readAttr T.AttrTFloat = getFloat >>= return . T.AttrFloat readAttr _ = getNum >>= return . T.AttrUInt
Text/Search/Sphinx/Indexable.hs view
@@ -4,7 +4,7 @@ ) where -import Data.ByteString.Lazy.UTF8 (toString)+import Data.Text (unpack) import qualified Text.Search.Sphinx.Types as T --import Text.Search.Sphinx.Types@@ -37,7 +37,7 @@ docEl (name, content) = normalEl name `text` indexableEl content indexableEl (T.AttrUInt i) = simpleText $ show i-indexableEl (T.AttrString s) = simpleText $ toString s+indexableEl (T.AttrString s) = simpleText $ unpack s indexableEl (T.AttrFloat f) = simpleText $ show f indexableEl _ = error "not implemented"
Text/Search/Sphinx/Put.hs view
@@ -8,6 +8,10 @@ import qualified Data.ByteString.Lazy as BS import qualified Text.Search.Sphinx.Types as T +import Data.Text (Text)+import qualified Data.Text.ICU.Convert as ICU+import qualified Data.ByteString as Strict (length)+ num = putWord32be . fromIntegral num64 i = putWord64be $ fromIntegral i @@ -39,3 +43,8 @@ foldPuts [] = return () foldPuts [p] = p foldPuts (p:ps) = p >> foldPuts ps++txt :: ICU.Converter -> Text -> Put+txt conv t = do let bs = ICU.fromUnicode conv t+ num (fromEnum $ Strict.length bs)+ putByteString bs
Text/Search/Sphinx/Types.hs view
@@ -6,7 +6,15 @@ import Data.ByteString.Lazy (ByteString) import Data.Int (Int64) import Data.Maybe (Maybe, isJust)+import Data.Text (Text,empty) +-- | Data structure representing one query. It can be sent with 'runQueries'+-- or 'runQueries'' to the server in batch mode.+data Query = Query { queryString :: Text -- ^ The actual query string+ , queryIndexes :: Text -- ^ The indexes, \"*\" means every index+ , queryComment :: Text -- ^ A comment string.+ } deriving (Show)+ -- | Search commands data SearchdCommand = ScSearch | ScExcerpt@@ -160,7 +168,7 @@ -- | Total amount of matching documents in index. , totalFound :: Int -- | processed words with the number of docs and the number of hits.- , words :: [(ByteString, Int, Int)]+ , words :: [(Text, Int, Int)] -- | List of attribute names returned in the result. -- | The Match will contain just the attribute values in the same order. , attributeNames :: [ByteString]@@ -169,15 +177,15 @@ -- | a single query result, runQueries returns a list of these data SingleResult = QueryOk QueryResult- | QueryWarning ByteString QueryResult- | QueryError Int ByteString+ | QueryWarning Text QueryResult+ | QueryError Int Text deriving (Show) -- | a result returned from searchd data Result a = Ok a- | Warning ByteString a- | Error Int ByteString- | Retry ByteString+ | Warning Text a+ | Error Int Text+ | Retry Text deriving (Show) data Match = Match {@@ -196,6 +204,6 @@ data Attr = AttrMulti [Attr] | AttrUInt Int | AttrBigInt Int64- | AttrString ByteString+ | AttrString Text | AttrFloat Float deriving (Show)
sphinx.cabal view
@@ -1,12 +1,12 @@ Name: sphinx-Version: 0.5.3.1+Version: 0.6.0 Synopsis: Haskell bindings to the Sphinx full-text searching daemon. Description: Haskell bindings to the Sphinx full-text searching daemon. Compatible with Sphinx version 2.0 Category: Text, Search, Database License: BSD3 License-file: LICENSE Author: Chris Eidhof <ce+sphinx@tupil.com>, Greg Weber-Maintainer: Greg Weber <greg@gregweber.info>+Maintainer: Greg Weber <greg@gregweber.info>, Aleksandar Dimitrov <aleks.dimitrov@gmail.com> homepage: https://github.com/gregwebs/haskell-sphinx-client cabal-version: >= 1.2@@ -31,7 +31,8 @@ Build-Depends: base >= 4 && < 5, binary, data-binary-ieee754, bytestring, network,- xml, utf8-string >= 0.3+ xml, + text < 0.12, text-icu < 0.7 if flag(version-1-1-beta) cpp-options: -DONE_ONE_BETA