Skip to content

Commit bbe5b61

Browse files
authored
Merge pull request #34 from ambarltd/sql-server-config
Add SQLServer config options
2 parents 4fcbfff + 065b546 commit bbe5b61

File tree

7 files changed

+95
-39
lines changed

7 files changed

+95
-39
lines changed

README.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ A YAML configuration file should describe all sources and destinations to be use
1818
data_sources:
1919

2020
# Connect to a PostgreSQL database
21-
- id: my_postgres_source
21+
- id: postgres_source
2222
description: Main events store
2323
type: postgres
2424
host: localhost
@@ -36,7 +36,7 @@ data_sources:
3636
partitioningColumn: aggregate_id
3737

3838
# Connect to a MySQL database
39-
- id: my_mysql_source
39+
- id: postgres_source
4040
description: Main events store
4141
type: mysql
4242
host: localhost
@@ -53,6 +53,24 @@ data_sources:
5353
autoIncrementingColumn: id
5454
partitioningColumn: aggregate_id
5555

56+
# Connect to an SQLServer database
57+
- id: sqlserver_source
58+
description: Main events store
59+
type: sqlserver
60+
host: localhost
61+
port: 1433
62+
username: my_user
63+
password: my_pass
64+
database: my_db
65+
table: events_table
66+
columns:
67+
- id
68+
- aggregate_id
69+
- sequence_number
70+
- payload
71+
autoIncrementingColumn: id
72+
partitioningColumn: aggregate_id
73+
5674
# Connections to your endpoint.
5775
# The Emulator will send data read from the databases to these endpoints.
5876
data_destinations:
@@ -66,8 +84,9 @@ data_destinations:
6684
password: password123
6785

6886
sources:
69-
- my_mysql_source
70-
- my_postgres_source
87+
- postgres_source
88+
- sqlserver_source
89+
- file_source
7190

7291
# Send data to a file. One entry per line.
7392
- id: file_destination
@@ -76,8 +95,9 @@ data_destinations:
7695
path: ./temp.file
7796

7897
sources:
79-
- my_mysql_source
80-
- my_postgres_source
98+
- postgres_source
99+
- sqlserver_source
100+
- file_source
81101
```
82102
83103
## Running the program

examples/config.yml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ data_sources:
3838
autoIncrementingColumn: id
3939
partitioningColumn: aggregate_id
4040

41+
# Connect to an SQLServer database
42+
- id: sqlserver_source
43+
description: Main events store
44+
type: sqlserver
45+
host: localhost
46+
port: 1433
47+
username: my_user
48+
password: my_pass
49+
database: my_db
50+
table: events_table
51+
columns:
52+
- id
53+
- aggregate_id
54+
- sequence_number
55+
- payload
56+
autoIncrementingColumn: id
57+
partitioningColumn: aggregate_id
58+
4159
# Connections to your endpoint.
4260
# The Emulator will send data read from the databases to these endpoints.
4361
data_destinations:
@@ -51,8 +69,9 @@ data_destinations:
5169
password: password123
5270

5371
sources:
54-
- postgres source
55-
- file source
72+
- postgres_source
73+
- sqlserver_source
74+
- file_source
5675

5776
# Send data to a file. One entry per line.
5877
- id: file_destination
@@ -62,4 +81,5 @@ data_destinations:
6281

6382
sources:
6483
- postgres_source
84+
- sqlserver_source
6585
- file_source

src/Ambar/Emulator.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import GHC.Generics (Generic)
1515
import System.Directory (doesFileExist)
1616
import System.FilePath ((</>))
1717

18-
import Ambar.Emulator.Connector.Postgres (PostgreSQLState)
19-
import Ambar.Emulator.Connector.MySQL (MySQLState)
2018
import Ambar.Emulator.Connector (Connector(..), connect, partitioner, encoder)
19+
import Ambar.Emulator.Connector.MicrosoftSQLServer (SQLServerState)
20+
import Ambar.Emulator.Connector.MySQL (MySQLState)
21+
import Ambar.Emulator.Connector.Postgres (PostgreSQLState)
2122

2223
import qualified Ambar.Emulator.Projector as Projector
2324
import Ambar.Emulator.Projector (Projection(..))
@@ -96,6 +97,7 @@ emulate logger_ config env = do
9697
case s_source source of
9798
SourcePostgreSQL _ -> StatePostgres def
9899
SourceMySQL _ -> StateMySQL def
100+
SourceSQLServer _ -> StateSQLServer def
99101
SourceFile _ -> StateFile ()
100102

101103
projectAll queue = forConcurrently_ (c_destinations env) (project queue)
@@ -134,6 +136,7 @@ newtype EmulatorState = EmulatorState
134136
data SavedState
135137
= StatePostgres PostgreSQLState
136138
| StateMySQL MySQLState
139+
| StateSQLServer SQLServerState
137140
| StateFile ()
138141
deriving (Generic)
139142
deriving anyclass (ToJSON, FromJSON)
@@ -160,6 +163,11 @@ toConnectorConfig source sstate =
160163
StateMySQL state ->
161164
return $ ConnectorConfig source msql state StateMySQL
162165
_ -> incompatible
166+
SourceSQLServer sqlserver ->
167+
case sstate of
168+
StateSQLServer state ->
169+
return $ ConnectorConfig source sqlserver state StateSQLServer
170+
_ -> incompatible
163171
SourceFile path ->
164172
case sstate of
165173
StateFile () ->

src/Ambar/Emulator/Config.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Data.Map.Strict (Map)
2727
import qualified Data.Map.Strict as Map
2828
import qualified Data.Yaml as Yaml
2929

30+
import Ambar.Emulator.Connector.MicrosoftSQLServer (SQLServer(..))
3031
import Ambar.Emulator.Connector.Postgres (PostgreSQL(..))
3132
import Ambar.Emulator.Connector.MySQL (MySQL(..))
3233
import Ambar.Emulator.Connector.File (FileConnector(..))
@@ -60,6 +61,7 @@ data Source
6061
= SourceFile FileConnector
6162
| SourcePostgreSQL PostgreSQL
6263
| SourceMySQL MySQL
64+
| SourceSQLServer SQLServer
6365

6466
data DataDestination = DataDestination
6567
{ d_id :: Id DataDestination
@@ -104,6 +106,7 @@ instance FromJSON DataSource where
104106
case t of
105107
"postgres" -> parsePostgreSQL o
106108
"mysql" -> parseMySQL o
109+
"sqlserver" -> parseSQLServer o
107110
"file" -> parseFile o
108111
_ -> fail $ unwords
109112
[ "Invalid data source type: '" <> t <> "'."
@@ -135,6 +138,18 @@ instance FromJSON DataSource where
135138
c_incrementingColumn <- o .: "autoIncrementingColumn"
136139
return $ SourceMySQL MySQL{..}
137140

141+
parseSQLServer o = do
142+
c_host <- o .: "host"
143+
c_port <- o .: "port"
144+
c_username <- o .: "username"
145+
c_password <- o .: "password"
146+
c_database <- o .: "database"
147+
c_table <- o .: "table"
148+
c_columns <- o .: "columns"
149+
c_partitioningColumn <- o .: "partitioningColumn"
150+
c_incrementingColumn <- o .: "autoIncrementingColumn"
151+
return $ SourceSQLServer SQLServer{..}
152+
138153
parseFile o = SourceFile . FileConnector <$> (o .: "path")
139154

140155
parseDataDestination

src/Ambar/Emulator/Projector.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import GHC.Generics (Generic)
2626
import Ambar.Emulator.Config (Id(..), DataDestination, DataSource(..), Source(..))
2727
import Ambar.Emulator.Queue.Topic (Topic, ReadError(..), PartitionCount(..))
2828
import qualified Ambar.Emulator.Queue.Topic as Topic
29+
import Ambar.Emulator.Connector.MicrosoftSQLServer (SQLServer(..))
2930
import Ambar.Emulator.Connector.Postgres (PostgreSQL(..))
3031
import Ambar.Emulator.Connector.MySQL (MySQL(..))
3132
import Ambar.Transport (Transport)
@@ -119,6 +120,12 @@ relevantFields source (Payload value) = renderPretty $
119120
| field <- [c_serialColumn, c_partitioningColumn]
120121
, Just v <- [KeyMap.lookup (fromString $ Text.unpack field) o]
121122
]
123+
SourceSQLServer SQLServer{..} ->
124+
fillSep $
125+
[ pretty field <> ":" <+> prettyJSON v
126+
| field <- [c_incrementingColumn, c_partitioningColumn]
127+
, Just v <- [KeyMap.lookup (fromString $ Text.unpack field) o]
128+
]
122129
where
123130
withObject f =
124131
case value of

tests/Test/Utils/Docker.hs

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ module Test.Utils.Docker
33
, withDocker
44
) where
55

6-
import Control.Concurrent.Async (race, wait, withAsync)
76
import Control.Concurrent (MVar, newMVar, modifyMVar)
8-
import Control.Concurrent.Async (race_)
97
import Control.Exception (ErrorCall(..), throwIO)
108
import Control.Monad (forM_)
119
import System.Exit (ExitCode(..))
@@ -24,15 +22,13 @@ import System.Process
2422
( CreateProcess(..)
2523
, StdStream(..)
2624
, proc
27-
, waitForProcess
25+
, getProcessExitCode
2826
, createPipe
29-
, cleanupProcess
30-
, terminateProcess
3127
, withCreateProcess
3228
)
3329
import System.IO.Unsafe (unsafePerformIO)
3430
import Utils.Async (withAsyncThrow)
35-
import Utils.Delay (delay, seconds)
31+
import Utils.Delay (seconds, every)
3632

3733
data DockerCommand
3834
= DockerRun
@@ -64,34 +60,24 @@ withDocker debug tag cmd act =
6460
}
6561
withCreateProcess create $ \stdin stdout stderr p -> do
6662
let pinfo = (stdin, stdout, stderr, p)
67-
withAsync (waitFor name pinfo) $ \a -> do
68-
r <- race (wait a) $ if debug
69-
then tracing name hread act
70-
else act hread
71-
terminate pinfo
72-
case r of
73-
Left _ -> error "impossible"
74-
Right v -> return v
63+
withAsyncThrow (waitFor name pinfo) $ do
64+
if debug
65+
then tracing name hread act
66+
else act hread
7567
where
76-
terminate pinfo = race_ (cleanupProcess pinfo) (forceEnd pinfo)
77-
78-
forceEnd (_,_,_,p) = do
79-
putStrLn $ "Forcing end of container: " <> tag
80-
delay (seconds 5)
81-
terminateProcess p
82-
8368
withPipe f = do
8469
(hread, hwrite) <- createPipe
8570
hSetBuffering hread LineBuffering
8671
hSetBuffering hwrite LineBuffering
8772
f hread hwrite
8873

89-
waitFor name (_,_,_,p) = do
90-
exit <- waitForProcess p
91-
throwIO $ ErrorCall $ case exit of
92-
ExitSuccess -> "unexpected successful termination of container " <> name
93-
ExitFailure code ->
94-
"docker failed with exit code" <> show code <> " for container " <> name
74+
waitFor name (_,_,_,p) = every (seconds 1) $ do
75+
mexit <- getProcessExitCode p
76+
forM_ mexit $ \exit ->
77+
throwIO $ ErrorCall $ case exit of
78+
ExitSuccess -> "unexpected successful termination of container " <> name
79+
ExitFailure code ->
80+
"docker failed with exit code" <> show code <> " for container " <> name
9581

9682
mkName = do
9783
number <- modifyMVar dockerImageNumber $ \n -> return (n + 1, n)

tests/Test/Utils/SQL.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import Data.Maybe (fromMaybe)
2929
import Data.Text (Text)
3030
import GHC.Generics (Generic)
3131
import System.IO.Unsafe (unsafePerformIO)
32-
import Test.Hspec (Spec, it, shouldBe)
32+
import Test.Hspec (Spec, it, shouldBe, sequential)
3333
import Test.Hspec.Expectations.Contrib (annotate)
3434

3535
import Ambar.Emulator.Connector (partitioner, encoder, Connector(..))
@@ -81,7 +81,7 @@ testGenericSQL
8181
-> (db -> table -> connector)
8282
-> Config table
8383
-> Spec
84-
testGenericSQL od withConnection mkConfig conf = do
84+
testGenericSQL od withConnection mkConfig conf = sequential $ do
8585
-- checks that our tests can connect to postgres
8686
it "connects" $
8787
with (PartitionCount 1) $ \conn table _ _ -> do

0 commit comments

Comments
 (0)