大改,整理项目结构,完成rust ffi调用,写好tcp接口

This commit is contained in:
LIm1tZz7 committed 2026-10-02 15:07:38 +08:00
1 parent df6d348995
commit 9758439b82
118 files changed
+8103 -6321

No files matched your search

+19 -22
View File
@@ -8,9 +8,9 @@ module Repl
import ChuSQL.CLI.Format (OutputFormat, formatName, renderResult, renderRows)
import ChuSQL.CLI.Script (Meta (..), errorHint, metaHelp, parseMeta, takeStatement)
import ChuSQL.CLI.Session (Session, accountTable, catalog, databases, roleViews, runStatement, sessionDatabase, switchDatabase)
import ChuSQL.Storage.IPC (SchemaColumn (..), TableInfo (..))
import ChuSQL.Web.Privileges (Grant (..), RoleView (..))
import ChuSQL.CLI.Session (Session, catalog, databases, roleViews, runStatement, sessionDatabase, switchDatabase)
import ChuSQL.Core.Protocol (SchemaColumn (..), TableInfo (..))
import ChuSQL.Interface.Protocol (Grant (..), RoleView (..))
import Control.Monad (forM_, when)
import Control.Monad.IO.Class (liftIO)
import Data.IORef (IORef, readIORef, writeIORef)
@@ -22,7 +22,7 @@ import System.IO (hIsTerminalDevice, stderr, stdin)
-- 交互层:提示符、多行输入、历史、元命令与错误提示。
-- | 交互循环;historyPath 为 Nothing 就不落盘历史
-- | 交互循环,没有历史文件就不落盘
runRepl :: Session -> IORef OutputFormat -> Maybe FilePath -> IO ()
runRepl session formatRef historyPath =
runInputT (defaultSettings{historyFile = historyPath}) (loop session formatRef T.empty)
@@ -41,6 +41,7 @@ runStatementOnce session format sql = do
Left message -> reportError message >> pure False
Right answer -> TIO.putStrLn (renderResult format answer) >> pure True
-- | 读一行输入,分派到元命令或语句缓冲
loop :: Session -> IORef OutputFormat -> Text -> InputT IO ()
loop session formatRef buffer = do
prompt <- liftIO (promptFor session buffer)
@@ -62,7 +63,7 @@ loop session formatRef buffer = do
remaining <- drain session formatRef extended
loop session formatRef remaining
-- | 提示符带上当前库;续行换个样子,方便看出语句还没写完;管道输入时不出提示符
-- | 生成提示符;续行与非终端输入另有样式
promptFor :: Session -> Text -> IO Text
promptFor session buffer = do
interactive <- hIsTerminalDevice stdin
@@ -83,6 +84,7 @@ drain session formatRef buffer = case takeStatement buffer of
when (not (T.null statement)) (runOne session formatRef statement)
drain session formatRef rest
-- | 执行一条语句并打印结果
runOne :: Session -> IORef OutputFormat -> Text -> InputT IO ()
runOne session formatRef statement = do
result <- liftIO (runStatement session statement)
@@ -92,6 +94,7 @@ runOne session formatRef statement = do
format <- liftIO (readIORef formatRef)
outputStrLn (T.unpack (renderResult format answer))
-- | 执行元命令,返回是否继续循环
runMeta :: Session -> IORef OutputFormat -> Meta -> InputT IO Bool
runMeta session formatRef meta = case meta of
MetaQuit -> pure False
@@ -120,17 +123,16 @@ listDatabases session = do
Left message -> liftIO (reportError message)
Right names -> outputStrLn (T.unpack (renderRows ["database"] (map (: []) names)))
-- | \dt:表清单(base 里补上账号表)
-- | \dt:表清单(含 server 补的账号表)
listTables :: Session -> InputT IO ()
listTables session = do
answer <- liftIO (catalog session)
case answer of
Left message -> liftIO (reportError message)
Right tables -> do
allTables <- liftIO (withAccountTable session tables)
outputStrLn (T.unpack (renderRows headers (map tableRow allTables)))
Right tables -> outputStrLn (T.unpack (renderRows headers (map tableRow tables)))
where
headers = ["table", "columns", "rows", "indexes"]
-- | 把表信息排成一行
tableRow info =
[ T.pack (tiTable info)
, tshow (length (tiColumns info))
@@ -144,14 +146,15 @@ describeTable session name = do
answer <- liftIO (catalog session)
case answer of
Left message -> liftIO (reportError message)
Right tables -> do
allTables <- liftIO (withAccountTable session tables)
case filter (matches name) allTables of
Right tables ->
case filter (matches name) tables of
[] -> liftIO (reportError ("unknown table: " <> name))
(info : _) -> outputStrLn (T.unpack (renderRows headers (map columnRow (tiColumns info))))
where
headers = ["column", "type", "primary", "unique", "nullable", "auto"]
-- | 表名忽略大小写比较
matches wanted info = T.toLower (T.pack (tiTable info)) == T.toLower wanted
-- | 把列信息排成一行
columnRow column =
[ T.pack (scName column)
, T.pack (scType column)
@@ -160,6 +163,7 @@ describeTable session name = do
, yesNo (scNullable column)
, yesNo (scAutoIncrement column)
]
-- | 布尔值转成 yes/no
yesNo True = "yes"
yesNo False = "no"
@@ -171,22 +175,15 @@ listRoles session = do
Left message -> liftIO (reportError message)
Right roles -> outputStrLn (T.unpack (renderRows ["role", "grants", "members"] (map roleRow roles)))
where
-- | 把角色信息排成一行
roleRow view =
[ roleName view
, if null (roleGrants view) then "-" else T.intercalate ", " (map grantText (roleGrants view))
, if null (roleMembers view) then "-" else T.intercalate ", " (roleMembers view)
]
-- | 拼一条授权说明
grantText grant = grantPrivilege grant <> " on " <> grantObject grant
-- | 当前库是 system 时,把账号表也列出来(与 Web 端一致)
withAccountTable :: Session -> [TableInfo] -> IO [TableInfo]
withAccountTable session tables = do
current <- sessionDatabase session
if current /= "system"
then pure tables
else do
extra <- accountTable session
pure (maybe tables (: tables) extra)
-- | 用 show 转成 Text
tshow :: Show a => a -> Text
tshow = T.pack . show