hbs2/fixme-new/lib/Fixme/State.hs

142 lines
3.6 KiB
Haskell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{-# OPTIONS_GHC -fno-warn-orphans #-}
module Fixme.State
( evolve
, withState
, insertFixme
, insertCommit
, selectCommit
, newCommit
) where
import Fixme.Prelude
import Fixme.Types
import Fixme.Config
import HBS2.System.Dir
import DBPipe.SQLite
import Data.HashMap.Strict qualified as HM
import Text.InterpolatedString.Perl6 (qc)
import Data.Maybe
instance ToField HashRef where
toField x = toField $ show $ pretty x
instance FromField HashRef where
fromField = fmap (fromString @HashRef) . fromField @String
evolve :: FixmePerks m => FixmeM m ()
evolve = do
dbpath <- localDBPath
debug $ "evolve" <+> pretty dbpath
mkdir (takeDirectory dbpath)
db <- newDBPipeEnv dbPipeOptsDef dbpath
withDB db do
createTables
withState :: forall m a . (FixmePerks m, MonadReader FixmeEnv m) => DBPipeM m a -> m a
withState what = do
db <- asks fixmeEnvDb
withDB db what
createTables :: FixmePerks m => DBPipeM m ()
createTables = do
-- тут все таблицы будут называться с префиксом
-- fixme, что бы может быть можно было встроить
-- в другую бд, если вдруг понадобится
ddl [qc|
create table if not exists fixmecommit
( hash text not null
, primary key (hash)
)
|]
ddl [qc|
create table if not exists fixme
( id text not null
, fixme blob not null
, primary key (id)
)
|]
ddl [qc|
create table if not exists fixmeattr
( fixme text not null
, ts integer null
, name text not null
, value text
, primary key (fixme,ts,name)
)
|]
ddl [qc| drop view if exists fixmeattrview |]
ddl [qc|
create view fixmeattrview as
with ranked as (
select
fixme,
name,
value,
row_number() over (partition by fixme, name order by ts desc nulls first) as rn
from fixmeattr
)
select
fixme,
name,
value
from ranked
where rn = 1;
|]
insertCommit :: FixmePerks m => GitHash -> DBPipeM m ()
insertCommit gh = do
insert [qc|
insert into fixmecommit (hash) values(?)
on conflict (hash) do nothing
|] (Only gh)
selectCommit :: FixmePerks m => GitHash -> DBPipeM m (Maybe GitHash)
selectCommit gh = do
select [qc|select hash from fixmecommit where hash = ?|] (Only gh)
<&> fmap fromOnly . listToMaybe
newCommit :: (FixmePerks m, MonadReader FixmeEnv m) => GitHash -> m Bool
newCommit gh = isNothing <$> withState (selectCommit gh)
insertFixme :: FixmePerks m => Fixme -> DBPipeM m ()
insertFixme fx@Fixme{..} = do
let fixme = serialise fx
let fxId = hashObject @HbSync fixme & HashRef
insert [qc|insert into fixme (id, fixme) values (?,?)
on conflict(id) do nothing
|] (fxId, fixme)
for_ (HM.toList fixmeAttr) $ \(n,v) -> do
insert [qc|
insert into fixmeattr(fixme,ts,name,value)
values (?,?,?,?)
on conflict (fixme,ts,name) do update set value = excluded.value
|] (fxId, fixmeTs, n, v)
insert [qc|
insert into fixmeattr(fixme,ts,name,value)
values (?,?,?,?)
on conflict (fixme,ts,name) do update set value = excluded.value
|] (fxId, fixmeTs, "fixme-tag", fixmeTag)
insert [qc|
insert into fixmeattr(fixme,ts,name,value)
values (?,?,?,?)
on conflict (fixme,ts,name) do update set value = excluded.value
|] (fxId, fixmeTs, "fixme-title", fixmeTitle)