git.iko.soy/typeable/postgresql-simple
on master help sign in
Add additional case-insensitive text support
commit87c6c2d783372a8a1f64b8b179ea4a909e4236ef authorMaximilian Tagher <feedback.tagher@gmail.com> dateThu 23 Nov 2017, 08:53 (9 years ago) parent70e19cd
6 files changed+58−1
CHANGES.md+6 postgresql-simple.cabal+1 src/Database/PostgreSQL/Simple/ToField.hs+11 src/Database/PostgreSQL/Simple/TypeInfo/Static.hs+21 test/Main.hs+16 tools/GenTypeInfo.hs+3−1
CHANGES.md+6
@@ -1,3 +1,9 @@
1+### Unreleased
2+
3+ * Added `ToField` instances for case-insensitive strict and lazy text.
4+ Added `citext` and `_citext` to `Database.PostgreSQL.Simple.TypeInfo.Static`.
5+ Thanks to Max Tagher for the implementation.
6+
17### Version 0.5.3.0 (2017-05-15)
28 * Refactored some rudimentary cursor handling code out of the
39 implementation of the fold operators, into a new
postgresql-simple.cabal+1
@@ -129,6 +129,7 @@ test-suite test
129129 , text
130130 , time
131131 , vector
132+ , case-insensitive
132133
133134 if !impl(ghc >= 7.6)
134135 build-depends:
src/Database/PostgreSQL/Simple/ToField.hs+11
@@ -42,6 +42,8 @@ import Database.PostgreSQL.Simple.Compat (toByteString)
4242
4343import qualified Data.ByteString as SB
4444import qualified Data.ByteString.Lazy as LB
45+import Data.CaseInsensitive (CI)
46+import qualified Data.CaseInsensitive as CI
4547import qualified Data.Text as ST
4648import qualified Data.Text.Encoding as ST
4749import qualified Data.Text.Lazy as LT
@@ -230,6 +232,15 @@ instance ToField LT.Text where
230232 toField = toField . LT.toStrict
231233 {-# INLINE toField #-}
232234
235+-- | citext
236+instance ToField (CI ST.Text) where
237+ toField = toField . CI.original
238+ {-# INLINE toField #-}
239+
240+-- | citext
241+instance ToField (CI LT.Text) where
242+ toField = toField . LT.toStrict . CI.original
243+ {-# INLINE toField #-}
233244
234245instance ToField UTCTime where
235246 toField = Plain . inQuotes . utcTimeToBuilder
src/Database/PostgreSQL/Simple/TypeInfo/Static.hs+21
@@ -132,6 +132,8 @@ module Database.PostgreSQL.Simple.TypeInfo.Static
132132 , _daterange
133133 , int8range
134134 , _int8range
135+ , citext
136+ , array_citext
135137 ) where
136138
137139import Database.PostgreSQL.LibPQ (Oid(..))
@@ -253,6 +255,8 @@ staticTypeInfo (Oid x) = case x of
253255 3913 -> Just _daterange
254256 3926 -> Just int8range
255257 3927 -> Just _int8range
258+ 60129 -> Just citext
259+ 60134 -> Just array_citext
256260 _ -> Nothing
257261
258262bool :: TypeInfo
@@ -1230,3 +1234,20 @@ _int8range = Array {
12301234 typname = "_int8range",
12311235 typelem = int8range
12321236 }
1237+
1238+citext :: TypeInfo
1239+citext = Basic {
1240+ typoid = Oid 60129,
1241+ typcategory = 'S',
1242+ typdelim = ',',
1243+ typname = "citext"
1244+ }
1245+
1246+array_citext :: TypeInfo
1247+array_citext = Array {
1248+ typoid = Oid 60134,
1249+ typcategory = 'A',
1250+ typdelim = ',',
1251+ typname = "_citext",
1252+ typelem = citext
1253+ }
test/Main.hs+16
@@ -23,6 +23,8 @@ import Data.Aeson
2323import Data.ByteString (ByteString)
2424import qualified Data.ByteString as B
2525import qualified Data.ByteString.Lazy.Char8 as BL
26+import Data.CaseInsensitive (CI)
27+import qualified Data.CaseInsensitive as CI
2628import Data.Map (Map)
2729import qualified Data.Map as Map
2830import Data.Text(Text)
@@ -50,6 +52,7 @@ tests env = testGroup "tests"
5052 , testCase "Array" . testArray
5153 , testCase "Array of nullables" . testNullableArray
5254 , testCase "HStore" . testHStore
55+ , testCase "citext" . testCIText
5356 , testCase "JSON" . testJSON
5457 , testCase "Savepoint" . testSavepoint
5558 , testCase "Unicode" . testUnicode
@@ -203,6 +206,19 @@ testHStore TestEnv{..} = do
203206 m' <- query conn "SELECT ?::hstore" m
204207 [m] @?= m'
205208
209+testCIText :: TestEnv -> Assertion
210+testCIText TestEnv{..} = do
211+ execute_ conn "CREATE EXTENSION IF NOT EXISTS citext"
212+ roundTrip (CI.mk "")
213+ roundTrip (CI.mk "UPPERCASE")
214+ roundTrip (CI.mk "lowercase")
215+ where
216+ roundTrip :: (CI Text) -> Assertion
217+ roundTrip cit = do
218+ let toPostgres = Only cit
219+ fromPostgres <- query conn "SELECT ?::citext" toPostgres
220+ [toPostgres] @?= fromPostgres
221+
206222testJSON :: TestEnv -> Assertion
207223testJSON TestEnv{..} = do
208224 roundTrip (Map.fromList [] :: Map Text Text)
tools/GenTypeInfo.hs+3−1
@@ -195,7 +195,9 @@ daterange
195195_daterange
196196int8range
197197_int8range
198−|]
198+citext
199+_citext array_citext
200+|] -- Note: You must enable the citext extension (CREATE EXTENSION IF NOT EXISTS citext) to generate the citext values
199201
200202instance IsString Blaze.Builder where
201203 fromString = Blaze.fromByteString . fromString