agent sqlite: initialize database in home directory by default (#74)

This commit is contained in:
Efim Poberezkin
2021-03-29 19:18:54 +04:00
committed by GitHub
parent da72efc20a
commit 08171e987d
7 changed files with 36 additions and 25 deletions

View File

@@ -10,7 +10,7 @@ See [simplex.chat](https://simplex.chat) website for chat demo and the explanati
SMP protocol is semi-formally defined [here](https://github.com/simplex-chat/protocol).
Currently only these features are available:
- simple 1-2-1 chat with multiple people in the same terminal window.
- simple 1-to-1 chat with multiple people in the same terminal window.
- auto-populated recipient name - just type your messages.
- default server is available to play with - `smp.simplex.im:5223` - and you can deploy your own (`smp-server` executable in this repo).
- no global identity or names visible to the server(s) - for the privacy of contacts and conversations.
@@ -51,16 +51,15 @@ $ dog-food
> **NOTE:** When running chat client executable built with the latter approach, if you encounter ``version `GLIBC_2.28' not found`` error, rebuild it with `haskell:8.8.4-stretch` base image instead (you'd have to change it in your local [Dockerfile](Dockerfile)).
`dog-food` (as in "eating your own dog food" - it is an early prototype) starts chat client with default parameters. By default, SQLite database file is created in the working directory (`smp-chat.db`), and the default SMP server is `smp.simplex.im:5223`.
`dog-food` (as in "eating your own dog food" - it is an early prototype) starts chat client with default parameters. By default, app data directory is created in the home directory (`~/.simplex`, or `%APPDATA%/simplex` on Windows), and SQLite database file `smp-chat.db` is initialized in it. The default SMP server is `smp.simplex.im:5223`.
To specify a different chat database location run:
To specify a different file path for the chat database use `-d` command line option:
```shell
$ mkdir ~/simplex
$ dog-food -d ~/simplex/my-chat.db
$ dog-food -d my-chat.db
```
You can deploy your own server and set client to use it via command line option:
If you deployed your own SMP server you can set client to use it via `-s` option:
```shell
$ dog-food -s smp.example.com:5223

View File

@@ -6,6 +6,7 @@ import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Char8 as B
import Options.Applicative
import Simplex.Messaging.Agent.Transmission (SMPServer (..), smpServerP)
import System.FilePath (combine)
import Types
data ChatOpts = ChatOpts
@@ -15,8 +16,9 @@ data ChatOpts = ChatOpts
termMode :: TermMode
}
chatOpts :: Parser ChatOpts
chatOpts =
chatOpts :: FilePath -> Parser ChatOpts
chatOpts appDir = do
let defaultDbFilePath = combine appDir "smp-chat.db"
ChatOpts
<$> option
(Just <$> str)
@@ -30,8 +32,8 @@ chatOpts =
( long "database"
<> short 'd'
<> metavar "DB_FILE"
<> help "sqlite database filename (smp-chat.db)"
<> value "smp-chat.db"
<> help ("sqlite database file path (" ++ defaultDbFilePath ++ ")")
<> value defaultDbFilePath
)
<*> option
parseSMPServer
@@ -60,12 +62,12 @@ parseTermMode = maybeReader $ \case
"editor" -> Just TermModeEditor
_ -> Nothing
getChatOpts :: IO ChatOpts
getChatOpts = execParser opts
getChatOpts :: FilePath -> IO ChatOpts
getChatOpts appDir = execParser opts
where
opts =
info
(chatOpts <**> helper)
(chatOpts appDir <**> helper)
( fullDesc
<> header "Chat prototype using Simplex Messaging Protocol (SMP)"
<> progDesc "Start chat with DB_FILE file and use SERVER as SMP server"

View File

@@ -27,6 +27,7 @@ import Simplex.Messaging.Agent.Env.SQLite
import Simplex.Messaging.Agent.Transmission
import Simplex.Messaging.Client (smpDefaultConfig)
import Simplex.Messaging.Util (bshow, raceAny_)
import System.Directory (getAppUserDataDirectory)
import Types
cfg :: AgentConfig
@@ -116,8 +117,11 @@ chatHelpInfo =
main :: IO ()
main = do
ChatOpts {dbFileName, smpServer, name, termMode} <- getChatOpts
putStrLn "simpleX chat prototype, \"/help\" for usage information"
appDir <- getAppUserDataDirectory "simplex"
ChatOpts {dbFileName, smpServer, name, termMode} <- getChatOpts appDir
putStrLn "simpleX chat prototype"
putStrLn $ "db: " ++ dbFileName
putStrLn "type \"/help\" for usage information"
let user = Contact <$> name
t <- getChatClient smpServer user
ct <- newChatTerminal (tbqSize cfg) user termMode

View File

@@ -19,6 +19,8 @@ dependencies:
- bytestring == 0.10.*
- containers
- cryptonite == 0.26.*
- directory == 1.3.*
- filepath == 1.4.*
- iso8601-time == 0.1.*
- memory == 0.15.*
- mtl

View File

@@ -18,7 +18,7 @@ data AgentConfig = AgentConfig
rsaKeySize :: Int,
connIdBytes :: Int,
tbqSize :: Natural,
dbFile :: String,
dbFile :: FilePath,
smpCfg :: SMPClientConfig
}

View File

@@ -40,19 +40,23 @@ import Simplex.Messaging.Protocol (MsgBody)
import qualified Simplex.Messaging.Protocol as SMP
import Simplex.Messaging.Util (liftIOEither)
import System.Exit (ExitCode (ExitFailure), exitWith)
import System.FilePath (takeDirectory)
import Text.Read (readMaybe)
import UnliftIO.Directory (createDirectoryIfMissing)
import qualified UnliftIO.Exception as E
-- * SQLite Store implementation
data SQLiteStore = SQLiteStore
{ dbFilename :: String,
{ dbFilePath :: FilePath,
dbConn :: DB.Connection
}
createSQLiteStore :: MonadUnliftIO m => String -> m SQLiteStore
createSQLiteStore dbFilename = do
store <- connectSQLiteStore dbFilename
createSQLiteStore :: MonadUnliftIO m => FilePath -> m SQLiteStore
createSQLiteStore dbFilePath = do
let dbDir = takeDirectory dbFilePath
createDirectoryIfMissing False dbDir
store <- connectSQLiteStore dbFilePath
compileOptions <- liftIO (DB.query_ (dbConn store) "pragma COMPILE_OPTIONS;" :: IO [[T.Text]])
let threadsafeOption = find (isPrefixOf "THREADSAFE=") (concat compileOptions)
liftIO $ case threadsafeOption of
@@ -65,10 +69,10 @@ createSQLiteStore dbFilename = do
liftIO . createSchema $ dbConn store
return store
connectSQLiteStore :: MonadUnliftIO m => String -> m SQLiteStore
connectSQLiteStore dbFilename = do
dbConn <- liftIO $ DB.open dbFilename
return SQLiteStore {dbFilename, dbConn}
connectSQLiteStore :: MonadUnliftIO m => FilePath -> m SQLiteStore
connectSQLiteStore dbFilePath = do
dbConn <- liftIO $ DB.open dbFilePath
return SQLiteStore {dbFilePath, dbConn}
instance (MonadUnliftIO m, MonadError StoreError m) => MonadAgentStore SQLiteStore m where
createRcvConn :: SQLiteStore -> RcvQueue -> m ()

View File

@@ -37,7 +37,7 @@ withStore = before createStore . after removeStore
removeStore :: SQLiteStore -> IO ()
removeStore store = do
DB.close $ dbConn store
removeFile $ dbFilename store
removeFile $ dbFilePath store
returnsResult :: (Eq a, Eq e, Show a, Show e) => ExceptT e IO a -> a -> Expectation
action `returnsResult` r = runExceptT action `shouldReturn` Right r