Skip to content

Commit 6259a2d

Browse files
authored
Merge pull request #713 from slingdata-io/v1.5.10
V1.5.10
2 parents ba79f80 + 29eff66 commit 6259a2d

52 files changed

Lines changed: 1079 additions & 151 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,6 @@ If you're using the python wrapper, decompress the downloaded binary and put the
195195

196196
We welcome contributions to improve Sling! Here are some guidelines to help you get started.
197197

198-
### Branch Naming Convention
199-
200-
When creating a new branch for your contribution, please use the following naming convention:
201-
202-
- `feature/your-feature-name` for new features
203-
- `bugfix/issue-description` for bug fixes
204-
- `docs/update-description` for documentation updates
205-
206198
### Testing Guidelines
207199

208200
Sling has three main test suites: Database, File and CLI. When contributing, please ensure that your changes pass the relevant tests.

cmd/sling/resource/llm_CONNECTION.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ Validate that a connection works properly:
316316
"action": "test",
317317
"input": {
318318
"connection": "MY_POSTGRES",
319+
"working_dir": "/optional/work/dir",
319320
"debug": true,
320321
"trace": false
321322
}
@@ -618,6 +619,7 @@ streams:
618619
"action": "test",
619620
"input": {
620621
"connection": "SALESFORCE_API",
622+
"working_dir": "/optional/work/dir",
621623
"endpoints": ["accounts", "contacts"],
622624
"limit": 10,
623625
"debug": true
@@ -665,6 +667,7 @@ streams:
665667
"action": "test",
666668
"input": {
667669
"connection": "MY_DB",
670+
"working_dir": "/optional/work/dir",
668671
"debug": true,
669672
"trace": true
670673
}

cmd/sling/resource/llm_PIPELINE.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,17 @@ The Sling MCP tool provides these pipeline commands:
6868
{
6969
"action": "parse",
7070
"input": {
71-
"file_path": "/path/to/pipeline.yaml"
71+
"file_path": "/path/to/pipeline.yaml",
72+
"working_dir": "/optional/work/dir"
7273
}
7374
}
7475

7576
// Run a pipeline
7677
{
7778
"action": "run",
7879
"input": {
79-
"file_path": "/path/to/pipeline.yaml"
80+
"file_path": "/path/to/pipeline.yaml",
81+
"working_dir": "/optional/work/dir"
8082
}
8183
}
8284
```
@@ -603,7 +605,8 @@ steps:
603605
{
604606
"action": "parse",
605607
"input": {
606-
"file_path": "/path/to/pipeline.yaml"
608+
"file_path": "/path/to/pipeline.yaml",
609+
"working_dir": "/optional/work/dir"
607610
}
608611
}
609612
```
@@ -614,6 +617,7 @@ steps:
614617
"action": "run",
615618
"input": {
616619
"file_path": "/path/to/pipeline.yaml",
620+
"working_dir": "/optional/work/dir",
617621
"env": {
618622
"CUSTOM_VAR": "value"
619623
}

cmd/sling/resource/mcp.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,14 @@ tools:
314314
315315
**For `action: "parse"`**:
316316
- `file_path` (string, required): The file path of the API specification.
317+
- `working_dir` (string, optional): Working directory to change to before running
317318
318319
**For `action: "docs"`**:
319320
- No parameters required (empty object)
320321
321322
**For `action: "test"`**:
322323
- `connection` (string, required): The name of the connection to test
324+
- `working_dir` (string, optional): Working directory to change to before running
323325
- `debug` (boolean, optional): Enable debug logging during the test (default: false)
324326
- `trace` (boolean, optional): Enable trace logging during the test (default: false)
325327
- `endpoints` (array, optional): Specify the endpoints to test (only for API connections)
@@ -342,6 +344,7 @@ tools:
342344
"action": "test",
343345
"input": {
344346
"connection": "MY_API",
347+
"working_dir": "/path/to/dir",
345348
"debug": true,
346349
"limit": 15
347350
}
@@ -351,7 +354,8 @@ tools:
351354
{
352355
"action": "parse",
353356
"input": {
354-
"file_path": "path/to/github_api.yaml"
357+
"file_path": "path/to/github_api.yaml",
358+
"working_dir": "/path/to/dir"
355359
}
356360
}
357361
```
@@ -446,9 +450,11 @@ tools:
446450
447451
**For `action: "parse"`**:
448452
- `file_path` (string, required): Path to the pipeline configuration file to read.
453+
- `working_dir` (string, optional): Working directory to change to before reading
449454
450455
**For `action: "run"`**:
451456
- `file_path` (string, required): Path to the pipeline configuration file to execute.
457+
- `working_dir` (string, optional): Working directory to change to before running
452458
- `env` (object, optional): Environment variables to set for the pipeline run.
453459
454460
**Output**: The output format depends on the action and audience:

cmd/sling/sling_cli.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ var cliRunFlags = []g.Flag{
117117
Type: "string",
118118
Description: "An object/map to specify the type that a column should be cast as (JSON or YAML).",
119119
},
120+
{
121+
Name: "cdc-options",
122+
Type: "string",
123+
Description: "in-line CDC options to configure change-capture mode (JSON or YAML).\n",
124+
},
120125
{
121126
Name: "streams",
122127
ShortName: "",

cmd/sling/sling_run.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ func processRun(c *g.CliSC) (ok bool, err error) {
4545
cfg := &sling.Config{
4646
Source: sling.Source{Options: &sling.SourceOptions{}},
4747
Target: sling.Target{Options: &sling.TargetOptions{}},
48+
// for CDC options
49+
ReplicationStream: &sling.ReplicationStreamConfig{},
4850
}
4951

5052
var replicationCfgPath, pipelineCfgPath, directoryPath string
@@ -208,6 +210,17 @@ func processRun(c *g.CliSC) (ok bool, err error) {
208210
selectStreams = strings.Split(cast.ToString(v), ",")
209211
case "examples":
210212
showExamples = cast.ToBool(v)
213+
case "cdc-options":
214+
payload := cast.ToString(v)
215+
options, err := parsePayload(payload, true)
216+
if err != nil {
217+
return ok, g.Error(err, "invalid cdc options -> %s", payload)
218+
}
219+
220+
err = g.JSONConvert(options, &cfg.ReplicationStream.CDCOptions)
221+
if err != nil {
222+
return ok, g.Error(err, "invalid cdc options -> %s", payload)
223+
}
211224
}
212225
}
213226

cmd/sling/sling_update.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -221,25 +221,27 @@ func checkUpdate() {
221221
)
222222
respMap := map[string]string{}
223223
g.JSONUnmarshal(respB, &respMap)
224-
if time.Now().Second()%6 == 0 && len(respMap) > 0 {
224+
if len(respMap) > 0 {
225225
updateVersion = respMap["version_latest"]
226-
if isDevChannel {
227-
if core.VersionSlash() != updateVersion && updateVersion != "" {
228-
updateMessage = env.GreenString(g.F("FYI there is a new sling dev build released => %s. You can run `sling update` to download it.", updateVersion))
229-
}
230-
} else {
231-
isNew, err := g.CompareVersions(core.Version, updateVersion)
232-
if err != nil {
233-
g.Debug("Error comparing versions: %s", err.Error())
234-
} else if isNew {
235-
updateMessage = env.GreenString(g.F("FYI there is a new sling version released (%s). %s", updateVersion, instruction))
236-
}
237-
}
238-
if message := respMap["media"]; message != "" {
239-
if updateMessage != "" {
240-
updateMessage = updateMessage + "\n" + env.BlueString(message)
226+
if time.Now().Second()%6 == 0 {
227+
if isDevChannel {
228+
if core.VersionSlash() != updateVersion && updateVersion != "" {
229+
updateMessage = env.GreenString(g.F("FYI there is a new sling dev build released => %s. You can run `sling update` to download it.", updateVersion))
230+
}
241231
} else {
242-
updateMessage = env.BlueString(message)
232+
isNew, err := g.CompareVersions(core.Version, updateVersion)
233+
if err != nil {
234+
g.Debug("Error comparing versions: %s", err.Error())
235+
} else if isNew {
236+
updateMessage = env.GreenString(g.F("FYI there is a new sling version released (%s). %s", updateVersion, instruction))
237+
}
238+
}
239+
if message := respMap["media"]; message != "" {
240+
if updateMessage != "" {
241+
updateMessage = updateMessage + "\n" + env.BlueString(message)
242+
} else {
243+
updateMessage = env.BlueString(message)
244+
}
243245
}
244246
}
245247
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM --platform=linux/amd64 ubuntu:jammy
2+
3+
RUN groupadd -r sling && useradd -r -g sling sling
4+
5+
RUN apt-get update && \
6+
DEBIAN_FRONTEND=noninteractive apt-get install -y curl ca-certificates unzip zstd && \
7+
cd /tmp && \
8+
curl -sSL -o dm.conda https://conda.anaconda.org/conda-forge/linux-64/libadbc-driver-manager-1.10.0-hb700be7_0.conda && \
9+
unzip -o dm.conda && \
10+
tar --use-compress-program=unzstd -xf pkg-libadbc-driver-manager-1.10.0-hb700be7_0.tar.zst && \
11+
cp lib/libadbc_driver_manager.so* /usr/local/lib/ && \
12+
ldconfig && \
13+
rm -rf /tmp/* && \
14+
apt-get clean && rm -rf /var/lib/apt/lists /var/cache/apt
15+
16+
# Copy sling binary (built externally by run_docker_test.sh)
17+
COPY --chown=sling:sling sling /usr/local/bin/sling
18+
RUN chmod 755 /usr/local/bin/sling
19+
20+
# Setup sling user home
21+
RUN mkdir -p /home/sling && chmod 755 /home/sling && chown sling:sling /home/sling
22+
USER sling
23+
24+
# Install dbc CLI + DuckDB ADBC driver
25+
RUN curl -LsSf https://dbc.columnar.tech/install.sh | sh && \
26+
/home/sling/.local/bin/dbc install duckdb
27+
28+
ENV PATH="${PATH}:/home/sling/.local/bin"
29+
ENV SLING_PACKAGE="DOCKER"
30+
31+
ENTRYPOINT ["sling"]
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM --platform=linux/arm64 ubuntu:jammy
2+
3+
RUN groupadd -r sling && useradd -r -g sling sling
4+
5+
RUN apt-get update && \
6+
DEBIAN_FRONTEND=noninteractive apt-get install -y curl ca-certificates unzip zstd && \
7+
cd /tmp && \
8+
curl -sSL -o dm.conda https://conda.anaconda.org/conda-forge/linux-aarch64/libadbc-driver-manager-1.10.0-hfefdfc9_0.conda && \
9+
unzip -o dm.conda && \
10+
tar --use-compress-program=unzstd -xf pkg-libadbc-driver-manager-1.10.0-hfefdfc9_0.tar.zst && \
11+
cp lib/libadbc_driver_manager.so* /usr/local/lib/ && \
12+
ldconfig && \
13+
rm -rf /tmp/* && \
14+
apt-get clean && rm -rf /var/lib/apt/lists /var/cache/apt
15+
16+
# Copy sling binary (built externally by run_docker_test.sh)
17+
COPY --chown=sling:sling sling /usr/local/bin/sling
18+
RUN chmod 755 /usr/local/bin/sling
19+
20+
# Setup sling user home
21+
RUN mkdir -p /home/sling && chmod 755 /home/sling && chown sling:sling /home/sling
22+
USER sling
23+
24+
# Install dbc CLI + DuckDB ADBC driver
25+
RUN curl -LsSf https://dbc.columnar.tech/install.sh | sh && \
26+
/home/sling/.local/bin/dbc install duckdb
27+
28+
ENV PATH="${PATH}:/home/sling/.local/bin"
29+
ENV SLING_PACKAGE="DOCKER"
30+
31+
ENTRYPOINT ["sling"]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# ADBC DuckDB regression test
2+
# Validates: purego struct return fix (Linux), duckdb_adbc_init entrypoint auto-detection
3+
# Requires: dbc CLI installed, ADBC driver manager, DUCKDB_ADBC and POSTGRES connections
4+
5+
steps:
6+
# Write test data into DuckDB via ADBC using inline replication from Postgres
7+
- replication:
8+
source: postgres
9+
target: DUCKDB_ADBC
10+
defaults:
11+
mode: full-refresh
12+
streams:
13+
"select 1 as id, 'hello' as name, 42.5 as value":
14+
sql: "select 1 as id, 'hello' as name, 42.5 as value"
15+
object: main.adbc_test
16+
17+
- log: "ADBC write completed"
18+
19+
# Read back from DuckDB via ADBC and verify
20+
- type: query
21+
connection: DUCKDB_ADBC
22+
query: select id, name, value from main.adbc_test order by id
23+
into: result
24+
25+
- log: "ADBC read result: {store.result}"
26+
27+
- type: check
28+
check: int_parse(store.result[0].id) == 1
29+
message: "Expected id=1, got {store.result[0].id}"
30+
31+
- type: check
32+
check: store.result[0].name == "hello"
33+
message: "Expected name='hello', got {store.result[0].name}"
34+
35+
- type: check
36+
check: float_parse(store.result[0].value) == 42.5
37+
message: "Expected value=42.5, got {store.result[0].value}"
38+
39+
- log: "ADBC DuckDB test PASSED"
40+
41+
# Cleanup
42+
- connection: DUCKDB_ADBC
43+
query: DROP TABLE IF EXISTS main.adbc_test

0 commit comments

Comments
 (0)