From 2aa98802e43391c353fc7efd256538adf4c0921a Mon Sep 17 00:00:00 2001 From: KovalevDima Date: Wed, 28 Oct 2026 22:58:36 +0000 Subject: [PATCH 1/6] Prepare clickhouse-proxy --- cabal.project | 1 + .../ClickHouseProxy/TcpServer.hs | 123 ++++++++++++++++++ ecosystem/clickhouse-proxy/LICENSE | 28 ++++ ecosystem/clickhouse-proxy/README.md | 1 + .../clickhouse-proxy/clickhouse-proxy.cabal | 43 ++++++ .../clickhouse-proxy/clickhouse-proxy.hs | 8 ++ library/ClickHaskell.cabal | 1 + library/ClickHaskell.hs | 9 -- library/ClickHaskell/Connection.hs | 10 -- library/ClickHaskell/Internal.hs | 18 +++ 10 files changed, 223 insertions(+), 19 deletions(-) create mode 100644 ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs create mode 100644 ecosystem/clickhouse-proxy/LICENSE create mode 100644 ecosystem/clickhouse-proxy/README.md create mode 100644 ecosystem/clickhouse-proxy/clickhouse-proxy.cabal create mode 100644 ecosystem/clickhouse-proxy/clickhouse-proxy.hs create mode 100644 library/ClickHaskell/Internal.hs diff --git a/cabal.project b/cabal.project index a3be0b10..d837ae56 100644 --- a/cabal.project +++ b/cabal.project @@ -2,6 +2,7 @@ packages: ./library ./ecosystem/tls ./ecosystem/eventlog2ch + ./ecosystem/clickhouse-proxy ./contribution ./contribution/modules/protocol-docs ./contribution/modules/visits diff --git a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs new file mode 100644 index 00000000..dab46417 --- /dev/null +++ b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs @@ -0,0 +1,123 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE OverloadedRecordDot #-} +module ClickHouseProxy.TcpServer ( + runTcpServer +) where + +import ClickHaskell (ToChType (..)) +import ClickHaskell.Protocol (ClientPacket (..), ExceptionPacket (..), HelloPacket (..), Serializable (..), ServerPacket (..)) +import Control.Concurrent (forkFinally) +import Control.Exception as E (SomeException, bracket, bracketOnError, catch, finally) +import Control.Monad (forever, void) +import Data.Binary (Get) +import Data.Binary.Get (Decoder (..), runGetIncremental) +import Data.ByteString as BS (ByteString, null, toStrict) +import Data.ByteString.Builder +import Data.ByteString.Char8 as BS (putStrLn) +import Data.ByteString.Char8 as BS8 (pack) +import Data.IORef (newIORef, readIORef, writeIORef) +import Data.List.NonEmpty as NE (head) +import Network.Socket +import Network.Socket.ByteString (recv, sendAll) + + +runTcpServer :: IO () +runTcpServer = + runTCPServer Nothing "9000" \sock -> do + BS.putStrLn "Opening connection" + buffer <- mkBuffer sock + talk buffer + where + talk buffer = do + packet <- readBuffer buffer (deserialize @ClientPacket 54459) + case packet of + Hello hello -> do + Prelude.putStrLn $ + "client: " <> show hello.client_name <> " " <> + "client_version_major: " <> show hello.client_version_major <> " " <> + "client_version_minor: " <> show hello.client_version_minor <> " " <> + "tcp_protocol_version: " <> "54459" <> " " <> + "default_database: " <> show hello.default_database <> " " <> + "user: " <> show hello.user <> " " <> + "pass: " <> show hello.pass <> " " <> + "" + writeConn buffer + . serialize 54459 + $ Exception MkExceptionPacket{ + code = 0, + name = toChType @_ @ByteString $ BS8.pack "Test exception", + message = toChType @_ @ByteString $ BS8.pack "\"Hello, World!\"", + stack_trace = toChType @_ @ByteString $ BS8.pack "", + nested = 0 + } + _other -> error "Unexpected packet" + + +runTCPServer :: Maybe HostName -> ServiceName -> (Socket -> IO a) -> IO a +runTCPServer mhost port server = do + addr <- resolve + E.bracket (open addr) close loop + where + resolve = do + let hints = defaultHints { + addrFlags = [AI_PASSIVE], + addrSocketType = Stream + } + NE.head <$> getAddrInfo (Just hints) mhost (Just port) + open addr = + E.bracketOnError (openSocket addr) close $ \sock -> do + setSocketOption sock ReuseAddr 1 + withFdSocket sock setCloseOnExecIfNeeded + bind sock $ addrAddress addr + listen sock 1024 + return sock + loop sock = + forever $ E.bracketOnError (accept sock) (close . fst) + $ \(conn, _peer) -> void $ + forkFinally (server conn) (const $ gracefulClose conn 5000) + + +-- Buffer + +mkBuffer :: Socket -> IO Buffer +mkBuffer sock = do + buff <- newIORef mempty + let + writeBuff = writeIORef buff + writeConn = sendAll sock . toStrict . toLazyByteString + readBuff = do + currentBuffer <- readIORef buff + if (not . BS.null) currentBuffer + then writeBuff mempty *> pure currentBuffer + else do + sockBytes <- recv sock 4096 + if BS.null sockBytes + then error "Connection closed" + else pure sockBytes + destroyBuff = do + catch @SomeException + (finally (shutdown sock ShutdownBoth) (close sock)) + (const $ pure ()) + writeBuff mempty + pure MkBuffer{writeConn, writeBuff, readBuff, destroyBuff} + where + + +data Buffer = MkBuffer + { readBuff :: IO ByteString + , destroyBuff :: IO () + , writeBuff :: ByteString -> IO () + , writeConn :: Builder -> IO () + } + +readBuffer :: Buffer -> Get a -> IO a +readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) + where + runBufferReader :: Decoder packet -> IO packet + runBufferReader dec = case dec of + (Partial decoder) -> readBuff >>= runBufferReader . decoder . Just + (Done leftover _consumed packet) -> packet <$ writeBuff leftover + (Fail _leftover _consumed msg) -> error ("Deserialization error: " <> msg) diff --git a/ecosystem/clickhouse-proxy/LICENSE b/ecosystem/clickhouse-proxy/LICENSE new file mode 100644 index 00000000..203b8458 --- /dev/null +++ b/ecosystem/clickhouse-proxy/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2026, Dmitry Kovalev + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ecosystem/clickhouse-proxy/README.md b/ecosystem/clickhouse-proxy/README.md new file mode 100644 index 00000000..4975e45d --- /dev/null +++ b/ecosystem/clickhouse-proxy/README.md @@ -0,0 +1 @@ +# clickhouse-proxy diff --git a/ecosystem/clickhouse-proxy/clickhouse-proxy.cabal b/ecosystem/clickhouse-proxy/clickhouse-proxy.cabal new file mode 100644 index 00000000..8d6e1d7d --- /dev/null +++ b/ecosystem/clickhouse-proxy/clickhouse-proxy.cabal @@ -0,0 +1,43 @@ +cabal-version: 3.0 + +name: clickhouse-proxy +version: 0.1 +author: Dmitry Kovalev +maintainer: Dmitry Kovalev +category: ClickHouse +synopsis: ClickHouse proxy +description: ClickHouse TCP protocol proxy +homepage: https://github.com/KovalevDima/clickhouse-proxy +bug-reports: https://github.com/KovalevDima/clickhouse-proxy +license: BSD-3-Clause +license-file: LICENSE +copyright: 2026 Dmitry Kovalev +build-type: Simple + +extra-doc-files: + README.md + +source-repository head + type: git + location: https://github.com/KovalevDima/clickhouse-proxy + +executable clickhouse-proxy + main-is: clickhouse-proxy.hs + hs-source-dirs: . + ghc-options: + -Wall + -Wunused-packages + build-depends: + -- Internal dependencies + ClickHaskell, + -- GHC included libraries + base >= 4.7 && <5, + bytestring, + binary, + -- External dependencies + network < 4, + other-modules: + ClickHouseProxy.TcpServer + default-language: Haskell2010 + default-extensions: + BlockArguments diff --git a/ecosystem/clickhouse-proxy/clickhouse-proxy.hs b/ecosystem/clickhouse-proxy/clickhouse-proxy.hs new file mode 100644 index 00000000..d54c3e83 --- /dev/null +++ b/ecosystem/clickhouse-proxy/clickhouse-proxy.hs @@ -0,0 +1,8 @@ +module Main where + +import ClickHouseProxy.TcpServer (runTcpServer) + +main :: IO () +main = do + putStrLn "Starting server" + runTcpServer diff --git a/library/ClickHaskell.cabal b/library/ClickHaskell.cabal index b7d82280..5e85e184 100644 --- a/library/ClickHaskell.cabal +++ b/library/ClickHaskell.cabal @@ -34,6 +34,7 @@ Library Exposed-Modules: ClickHaskell ClickHaskell.Protocol + ClickHaskell.Internal Other-Modules: ClickHaskell.Connection ClickHaskell.Protocol.Client diff --git a/library/ClickHaskell.hs b/library/ClickHaskell.hs index f410dd04..63d5cc26 100644 --- a/library/ClickHaskell.hs +++ b/library/ClickHaskell.hs @@ -313,15 +313,6 @@ mkQueryArgs MkConnectionState {..} settings parameters query = MkQueryPacketArgs -- ** Connection -readBuffer :: Buffer -> Get a -> IO a -readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) - where - runBufferReader :: Decoder packet -> IO packet - runBufferReader dec = case dec of - (Partial decoder) -> readBuff >>= runBufferReader . decoder . Just - (Done leftover _consumed packet) -> packet <$ writeBuff leftover - (Fail _leftover _consumed msg) -> throwIO (InternalError $ DeserializationError msg) - withConnection :: HasCallStack => Connection -> (ConnectionState -> IO a) -> IO a withConnection (MkConnection connStateMVar) f = diff --git a/library/ClickHaskell/Connection.hs b/library/ClickHaskell/Connection.hs index 787ec13b..eac810d0 100644 --- a/library/ClickHaskell/Connection.hs +++ b/library/ClickHaskell/Connection.hs @@ -33,16 +33,6 @@ data ConnectionError -- ^ Occurs on 'readSock' empty @""@ result deriving (Show, Exception) -{- | - These exceptions might indicate internal bugs. - - If you encounter one, please report it. --} -data InternalError - = UnexpectedPacketType UVarInt - | DeserializationError String - deriving (Show, Exception) - writeToConnection :: ConnectionState -> (ProtocolRevision -> Builder) -> IO () writeToConnection MkConnectionState{revision, buffer} serializer = (writeConn buffer) (serializer revision) diff --git a/library/ClickHaskell/Internal.hs b/library/ClickHaskell/Internal.hs new file mode 100644 index 00000000..36e44779 --- /dev/null +++ b/library/ClickHaskell/Internal.hs @@ -0,0 +1,18 @@ +module ClickHaskell.Internal ( + Buffer(..), + mkBuffer, + readBuffer, +) where +import ClickHaskell.Connection +import Data.Binary.Get +import Control.Exception + + +readBuffer :: Buffer -> Get a -> IO a +readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) + where + runBufferReader :: Decoder packet -> IO packet + runBufferReader dec = case dec of + (Partial decoder) -> readBuff >>= runBufferReader . decoder . Just + (Done leftover _consumed packet) -> packet <$ writeBuff leftover + (Fail _leftover _consumed msg) -> throwIO (InternalError $ DeserializationError msg) From 66ecfbf35aaee501e0bfdcb7eaaaed5be677542f Mon Sep 17 00:00:00 2001 From: KovalevDima Date: Wed, 28 Oct 2026 22:59:33 +0000 Subject: [PATCH 2/6] Use ClickHaskell internals --- .../ClickHouseProxy/TcpServer.hs | 32 +------------------ library/ClickHaskell.hs | 9 ++++++ library/ClickHaskell/Internal.hs | 12 ------- 3 files changed, 10 insertions(+), 43 deletions(-) diff --git a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs index dab46417..ed904aad 100644 --- a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs +++ b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs @@ -9,6 +9,7 @@ module ClickHouseProxy.TcpServer ( import ClickHaskell (ToChType (..)) import ClickHaskell.Protocol (ClientPacket (..), ExceptionPacket (..), HelloPacket (..), Serializable (..), ServerPacket (..)) +import ClickHaskell.Internal import Control.Concurrent (forkFinally) import Control.Exception as E (SomeException, bracket, bracketOnError, catch, finally) import Control.Monad (forever, void) @@ -82,37 +83,6 @@ runTCPServer mhost port server = do -- Buffer -mkBuffer :: Socket -> IO Buffer -mkBuffer sock = do - buff <- newIORef mempty - let - writeBuff = writeIORef buff - writeConn = sendAll sock . toStrict . toLazyByteString - readBuff = do - currentBuffer <- readIORef buff - if (not . BS.null) currentBuffer - then writeBuff mempty *> pure currentBuffer - else do - sockBytes <- recv sock 4096 - if BS.null sockBytes - then error "Connection closed" - else pure sockBytes - destroyBuff = do - catch @SomeException - (finally (shutdown sock ShutdownBoth) (close sock)) - (const $ pure ()) - writeBuff mempty - pure MkBuffer{writeConn, writeBuff, readBuff, destroyBuff} - where - - -data Buffer = MkBuffer - { readBuff :: IO ByteString - , destroyBuff :: IO () - , writeBuff :: ByteString -> IO () - , writeConn :: Builder -> IO () - } - readBuffer :: Buffer -> Get a -> IO a readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) where diff --git a/library/ClickHaskell.hs b/library/ClickHaskell.hs index 63d5cc26..f410dd04 100644 --- a/library/ClickHaskell.hs +++ b/library/ClickHaskell.hs @@ -313,6 +313,15 @@ mkQueryArgs MkConnectionState {..} settings parameters query = MkQueryPacketArgs -- ** Connection +readBuffer :: Buffer -> Get a -> IO a +readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) + where + runBufferReader :: Decoder packet -> IO packet + runBufferReader dec = case dec of + (Partial decoder) -> readBuff >>= runBufferReader . decoder . Just + (Done leftover _consumed packet) -> packet <$ writeBuff leftover + (Fail _leftover _consumed msg) -> throwIO (InternalError $ DeserializationError msg) + withConnection :: HasCallStack => Connection -> (ConnectionState -> IO a) -> IO a withConnection (MkConnection connStateMVar) f = diff --git a/library/ClickHaskell/Internal.hs b/library/ClickHaskell/Internal.hs index 36e44779..b60a42e0 100644 --- a/library/ClickHaskell/Internal.hs +++ b/library/ClickHaskell/Internal.hs @@ -1,18 +1,6 @@ module ClickHaskell.Internal ( Buffer(..), mkBuffer, - readBuffer, ) where import ClickHaskell.Connection -import Data.Binary.Get -import Control.Exception - -readBuffer :: Buffer -> Get a -> IO a -readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) - where - runBufferReader :: Decoder packet -> IO packet - runBufferReader dec = case dec of - (Partial decoder) -> readBuff >>= runBufferReader . decoder . Just - (Done leftover _consumed packet) -> packet <$ writeBuff leftover - (Fail _leftover _consumed msg) -> throwIO (InternalError $ DeserializationError msg) From 51b65cb47223c8bad255e0e76c90c99716b4e8d6 Mon Sep 17 00:00:00 2001 From: KovalevDima Date: Thu, 29 Oct 2026 19:40:58 +0000 Subject: [PATCH 3/6] Fix proxy build --- .../clickhouse-proxy/ClickHouseProxy/TcpServer.hs | 15 +++++---------- library/ClickHaskell.hs | 1 + library/ClickHaskell/Connection.hs | 10 ++++++++++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs index ed904aad..66322fe8 100644 --- a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs +++ b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs @@ -7,29 +7,26 @@ module ClickHouseProxy.TcpServer ( runTcpServer ) where -import ClickHaskell (ToChType (..)) -import ClickHaskell.Protocol (ClientPacket (..), ExceptionPacket (..), HelloPacket (..), Serializable (..), ServerPacket (..)) +import ClickHaskell (ToChType (..), defaultMkBufferArgs) import ClickHaskell.Internal +import ClickHaskell.Protocol (ClientPacket (..), ExceptionPacket (..), HelloPacket (..), Serializable (..), ServerPacket (..)) import Control.Concurrent (forkFinally) -import Control.Exception as E (SomeException, bracket, bracketOnError, catch, finally) +import Control.Exception as E (bracket, bracketOnError) import Control.Monad (forever, void) import Data.Binary (Get) import Data.Binary.Get (Decoder (..), runGetIncremental) -import Data.ByteString as BS (ByteString, null, toStrict) -import Data.ByteString.Builder +import Data.ByteString as BS (ByteString) import Data.ByteString.Char8 as BS (putStrLn) import Data.ByteString.Char8 as BS8 (pack) -import Data.IORef (newIORef, readIORef, writeIORef) import Data.List.NonEmpty as NE (head) import Network.Socket -import Network.Socket.ByteString (recv, sendAll) runTcpServer :: IO () runTcpServer = runTCPServer Nothing "9000" \sock -> do BS.putStrLn "Opening connection" - buffer <- mkBuffer sock + buffer <- mkBuffer =<< defaultMkBufferArgs "" sock talk buffer where talk buffer = do @@ -81,8 +78,6 @@ runTCPServer mhost port server = do forkFinally (server conn) (const $ gracefulClose conn 5000) --- Buffer - readBuffer :: Buffer -> Get a -> IO a readBuffer MkBuffer{readBuff, writeBuff} parser = runBufferReader (runGetIncremental parser) where diff --git a/library/ClickHaskell.hs b/library/ClickHaskell.hs index f410dd04..3a060693 100644 --- a/library/ClickHaskell.hs +++ b/library/ClickHaskell.hs @@ -20,6 +20,7 @@ module ClickHaskell , overrideOsUser , overrideDefaultPort , overrideMaxRevision + , defaultMkBufferArgs {- * Statements and commands -} diff --git a/library/ClickHaskell/Connection.hs b/library/ClickHaskell/Connection.hs index eac810d0..787ec13b 100644 --- a/library/ClickHaskell/Connection.hs +++ b/library/ClickHaskell/Connection.hs @@ -33,6 +33,16 @@ data ConnectionError -- ^ Occurs on 'readSock' empty @""@ result deriving (Show, Exception) +{- | + These exceptions might indicate internal bugs. + + If you encounter one, please report it. +-} +data InternalError + = UnexpectedPacketType UVarInt + | DeserializationError String + deriving (Show, Exception) + writeToConnection :: ConnectionState -> (ProtocolRevision -> Builder) -> IO () writeToConnection MkConnectionState{revision, buffer} serializer = (writeConn buffer) (serializer revision) From ba54c5f6f5ba89d1b3f2415518f483ce27f9d13c Mon Sep 17 00:00:00 2001 From: KovalevDima Date: Thu, 29 Oct 2026 21:08:49 +0000 Subject: [PATCH 4/6] Move defaultMkBufferArgs to internal module --- ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs | 2 +- library/ClickHaskell.hs | 1 - library/ClickHaskell/Internal.hs | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs index 66322fe8..b4e44045 100644 --- a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs +++ b/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs @@ -7,7 +7,7 @@ module ClickHouseProxy.TcpServer ( runTcpServer ) where -import ClickHaskell (ToChType (..), defaultMkBufferArgs) +import ClickHaskell (ToChType (..)) import ClickHaskell.Internal import ClickHaskell.Protocol (ClientPacket (..), ExceptionPacket (..), HelloPacket (..), Serializable (..), ServerPacket (..)) import Control.Concurrent (forkFinally) diff --git a/library/ClickHaskell.hs b/library/ClickHaskell.hs index 3a060693..f410dd04 100644 --- a/library/ClickHaskell.hs +++ b/library/ClickHaskell.hs @@ -20,7 +20,6 @@ module ClickHaskell , overrideOsUser , overrideDefaultPort , overrideMaxRevision - , defaultMkBufferArgs {- * Statements and commands -} diff --git a/library/ClickHaskell/Internal.hs b/library/ClickHaskell/Internal.hs index b60a42e0..b3545200 100644 --- a/library/ClickHaskell/Internal.hs +++ b/library/ClickHaskell/Internal.hs @@ -1,6 +1,8 @@ module ClickHaskell.Internal ( Buffer(..), mkBuffer, + defaultMkBufferArgs, ) where -import ClickHaskell.Connection +-- Internal +import ClickHaskell.Connection From 267b835930a76a5e5f0369bce71dd291ac5e08e5 Mon Sep 17 00:00:00 2001 From: KovalevDima Date: Fri, 30 Oct 2026 22:40:42 +0000 Subject: [PATCH 5/6] Add PoC to proxy --- .../ClickHouseProxy/TcpServer.hs | 0 ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/LICENSE | 0 ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/README.md | 0 .../clickhouse-proxy.cabal | 0 .../clickhouse-proxy.hs | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/ClickHouseProxy/TcpServer.hs (100%) rename ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/LICENSE (100%) rename ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/README.md (100%) rename ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/clickhouse-proxy.cabal (100%) rename ecosystem/{clickhouse-proxy => PoC-clickhouse-proxy}/clickhouse-proxy.hs (100%) diff --git a/ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs b/ecosystem/PoC-clickhouse-proxy/ClickHouseProxy/TcpServer.hs similarity index 100% rename from ecosystem/clickhouse-proxy/ClickHouseProxy/TcpServer.hs rename to ecosystem/PoC-clickhouse-proxy/ClickHouseProxy/TcpServer.hs diff --git a/ecosystem/clickhouse-proxy/LICENSE b/ecosystem/PoC-clickhouse-proxy/LICENSE similarity index 100% rename from ecosystem/clickhouse-proxy/LICENSE rename to ecosystem/PoC-clickhouse-proxy/LICENSE diff --git a/ecosystem/clickhouse-proxy/README.md b/ecosystem/PoC-clickhouse-proxy/README.md similarity index 100% rename from ecosystem/clickhouse-proxy/README.md rename to ecosystem/PoC-clickhouse-proxy/README.md diff --git a/ecosystem/clickhouse-proxy/clickhouse-proxy.cabal b/ecosystem/PoC-clickhouse-proxy/clickhouse-proxy.cabal similarity index 100% rename from ecosystem/clickhouse-proxy/clickhouse-proxy.cabal rename to ecosystem/PoC-clickhouse-proxy/clickhouse-proxy.cabal diff --git a/ecosystem/clickhouse-proxy/clickhouse-proxy.hs b/ecosystem/PoC-clickhouse-proxy/clickhouse-proxy.hs similarity index 100% rename from ecosystem/clickhouse-proxy/clickhouse-proxy.hs rename to ecosystem/PoC-clickhouse-proxy/clickhouse-proxy.hs From 043ba7656230f569f3a38d4c135d439dc9e2cc35 Mon Sep 17 00:00:00 2001 From: KovalevDima Date: Fri, 30 Oct 2026 22:42:25 +0000 Subject: [PATCH 6/6] Update path --- cabal.project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal.project b/cabal.project index d837ae56..e1265f94 100644 --- a/cabal.project +++ b/cabal.project @@ -2,7 +2,7 @@ packages: ./library ./ecosystem/tls ./ecosystem/eventlog2ch - ./ecosystem/clickhouse-proxy + ./ecosystem/PoC-clickhouse-proxy ./contribution ./contribution/modules/protocol-docs ./contribution/modules/visits