packages feed

CabalSearch 0.0.1 → 0.0.2

raw patch · 2 files changed

+70/−1 lines, 2 files

Files

+ CabalIndex.hs view
@@ -0,0 +1,68 @@+module CabalIndex+       ( buildDatabase+       , queryPackages)+       where++import Control.Monad++import System.Directory      (renameFile)+import System.FilePath       ((</>))+import System.Process        (readProcess)++import Database.HDBC+import Database.HDBC.Sqlite3++import qualified Data.List as L+++{-| Insert packages into table -}+populate :: IConnection c => c -> [(String, String)] -> IO ()+populate conn ps =+  do stmt <- prepare conn "INSERT INTO packages VALUES (?, ?)"+     executeMany stmt $ map (\(n,m) -> [toSql n, toSql m]) ps++{-| Create table for packages -}+createTable :: IConnection c => c -> IO ()+createTable conn =+  void $ run conn "CREATE TABLE packages (name VARCHAR(16) PRIMARY KEY, meta VARCHAR(128))" []++{-| Create and populate a new database, replacing the old -}+buildDatabase :: FilePath -> String -> IO ()+buildDatabase dbDir dbName =+  do -- place tmp file in same dir as db to allow atomic move+     let tmpDb = dbDir </> dbName ++ "-partial"+     -- build database in temporary path+     conn <- connectSqlite3 tmpDb+     createTable conn+     populate conn =<< parseCabal+     -- commit and disconnect+     commit conn+     disconnect conn+     -- move new database over old one+     renameFile tmpDb $ dbDir </> dbName++{-| Query a database, using the output from Cabal -}+queryPackages :: FilePath -> String -> IO [(String, String)]+queryPackages db term =+  do conn <- connectSqlite3 db+     rows <- quickQuery conn "SELECT * FROM packages WHERE name LIKE ?" [toSql $ '%':term++"%"]+     return $ map (\[n,m] -> (fromSql n :: String, fromSql m :: String)) rows+++{-| List packages using Cabal and parse the result to (name, meta) -}+parseCabal :: IO [(String, String)]+parseCabal = go `fmap` lines `fmap` readProcess "cabal" ["list"] []+  where+    go [] = []+    go (('*':' ':name):rest) =+      let (meta, rest') = gm [] rest+      in (name, L.intercalate "\n" meta) : go rest'+    go l = error $ "Unexpected cabal output" ++ show l++    gm m [] = (m, [])+    gm m (rest@(('*':_):_)) = (m, rest)+    gm m (x:xs)+      | L.null x  = gm m xs+      | otherwise = gm (m ++ [x]) xs++
CabalSearch.cabal view
@@ -1,5 +1,5 @@ name:           CabalSearch-version:        0.0.1+version:        0.0.2 license:        BSD3 license-file:   LICENSE category:       Utils@@ -23,6 +23,7 @@  executable cabalsearch     main-is: Main.hs+    other-modules: CabalIndex      build-depends:         base == 4.*,