Skip to content

Commit a937022

Browse files
Merge pull request #4 from cloudquery/feat/upgrade-sdk-v4
feat: Upgrade to SDK v4
2 parents cb859b6 + d40a370 commit a937022

28 files changed

Lines changed: 1053 additions & 295 deletions

.github/workflows/test.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ jobs:
2323
- name: golangci-lint
2424
uses: golangci/golangci-lint-action@v3
2525
with:
26-
version: v1.50.1
26+
version: v1.54.2
27+
- name: Setup CloudQuery
28+
if: github.event_name == 'pull_request'
29+
uses: cloudquery/setup-cloudquery@v3
30+
with:
31+
version: v3.27.1
2732
- name: Get dependencies
2833
run: go get -t -d ./...
2934
- name: Build

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
dist/
22
vendor/
33
bin/
4-
cq-source-simple-analytics
4+
cq-source-simple-analytics
5+
cloudquery
6+
cloudquery.log
7+
.DS_Store
8+
.idea

.golangci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ linters:
8080
enable:
8181
- asciicheck
8282
- bodyclose
83-
- depguard
8483
- dupl
8584
- errcheck
8685
- gocritic

Makefile

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
1+
.PHONY: build
2+
build:
3+
go build
4+
15
.PHONY: test
26
test:
3-
go test -timeout 3m ./...
7+
go test -short -race -timeout 3m ./...
48

59
.PHONY: lint
610
lint:
711
@golangci-lint run --timeout 10m --verbose
812

913
.PHONY: gen-docs
10-
gen-docs:
11-
rm -rf ./docs/tables/*
12-
go run main.go doc ./docs/tables
14+
gen-docs: build
15+
@command -v cloudquery >/dev/null 2>&1 || { \
16+
echo "Error: 'cloudquery' command not found. Please install it before running gen-docs."; \
17+
echo "You can install it by following the instructions at: https://www.cloudquery.io/docs/quickstart"; \
18+
exit 1; \
19+
}
20+
rm -rf docs/tables
21+
cloudquery tables --format markdown --output-dir docs/ test/config.yml
22+
mv -vf docs/simple-analytics docs/tables
1323

1424
# All gen targets
1525
.PHONY: gen

README.md

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,27 @@
33
[![test](https://github.com/cloudquery/cq-source-simple-analytics/actions/workflows/test.yaml/badge.svg)](https://github.com/cloudquery/cq-source-simple-analytics/actions/workflows/test.yaml)
44
[![Go Report Card](https://goreportcard.com/badge/github.com/cloudquery/cq-source-simple-analytics)](https://goreportcard.com/report/github.com/cloudquery/cq-source-simple-analytics)
55

6-
A [Simple Analytics](https://simpleanalytics.com/) source plugin for CloudQuery that loads raw page view and event data from Simple Analytics to any database, data warehouse or data lake supported by [CloudQuery](https://www.cloudquery.io/), such as PostgreSQL, BigQuery, Athena, and many more.
6+
A [Simple Analytics](https://simpleanalytics.com/) source plugin for CloudQuery that loads raw page view and event data from Simple Analytics to any database, data warehouse or data lake supported by [CloudQuery](https://cloudquery.io/), such as PostgreSQL, BigQuery, Athena, and many more.
77

88
## Links
99

10-
- [CloudQuery Quickstart Guide](https://www.cloudquery.io/docs/quickstart)
10+
- [CloudQuery Quickstart Guide](https://cloudquery.io/docs/quickstart)
1111
- [Supported Tables](docs/tables/README.md)
1212

1313
## Configuration
1414

15-
The following source configuration file will sync all data points for `mywebsite.com` to a PostgreSQL database. See [the CloudQuery Quickstart](https://www.cloudquery.io/docs/quickstart) for more information on how to configure the source and destination.
15+
The following source configuration file will sync all data points for `mywebsite.com` to a PostgreSQL database. See [CloudQuery Quickstart](https://cloudquery.io/docs/quickstart) for more information on how to configure the source and destination.
1616

1717
```yaml
1818
kind: source
1919
spec:
20-
name: "simpleanalytics"
21-
path: "simpleanalytics/simpleanalytics"
22-
version: "${VERSION}"
23-
# backend: "local" # use this to enable incremental syncing
20+
name: "simple-analytics"
21+
path: "simple-analytics/simple-analytics"
22+
version: "v2.0.0"
23+
# use this to enable incremental syncing
24+
# backend_options:
25+
# table_name: "cq_state_simpleanalytics
26+
# connection: "@@plugins.DESTINATION_NAME.connection"
2427
tables:
2528
["*"]
2629
destinations:
@@ -39,46 +42,49 @@ spec:
3942

4043
### Plugin Spec
4144

42-
- `user_id` (string, required):
45+
- `user_id` (`string`) (required)
4346

4447
A user ID from Simple Analytics, obtained from the [account settings](https://simpleanalytics.com/account) page. It should start with `sa_user_id...`
4548

46-
- `api_key` (string, required):
49+
- `api_key` (`string`) (required)
4750

4851
An API Key from Simple Analytics, obtained from the [account settings](https://simpleanalytics.com/account) page. It should start with `sa_api_key...`
4952

50-
- `websites` (array, required):
53+
- `websites` (`list`) (required)
5154

5255
A list of websites to sync data for. Each website should have the following fields:
5356

54-
- `hostname` (string, required):
57+
- `hostname` (`string`) (required)
5558

5659
The hostname of the website to sync data for. This should be the same as the hostname in Simple Analytics.
5760

58-
- `metadata_fields` (array[string], optional):
61+
- `metadata_fields` (`[]string`) (optional)
5962

6063
A list of metadata fields to sync, e.g. `["path_text", "created_at_time"]`. If not specified, no metadata fields will be synced.
6164

62-
- `start_date` (string, optional):
65+
- `start_date` (`string`) (optional)
6366

6467
The date to start syncing data from. If not specified, the plugin will sync data from the beginning of time (or use a start time defined by `period`, if set).
6568

66-
- `end_date` (string, optional):
69+
- `end_date` (`string`) (optional)
6770

6871
The date to stop syncing data at. If not specified, the plugin will sync data until the current date.
6972

70-
- `period` (string, optional):
73+
- `period` (`string`) (optional)
7174

7275
The duration of the time window to fetch historical data for, in days, months or years. It is used to calculate `start_date` if it is not specified. If `start_date` is specified, duration is ignored. Examples:
7376
- `7d`: last 7 days
7477
- `3m`: last 3 months
7578
- `1y`: last year
7679

80+
- `concurrency` (`integer`) (optional`) (default: `1000`)
81+
82+
Best effort maximum number of Go routines to use. Lower this number to reduce memory usage.
7783

7884
## Incremental Syncing
7985

8086
The Simple Analytics plugin supports incremental syncing. This means that only new data points will be fetched from Simple Analytics and loaded into your destination. This is done by keeping track of the last date a sync was done, and only fetching new data from that date onwards.
81-
To enable this, `backend` option must be set in the spec (as shown in the example config above). By default, incremental syncing is turned off. Also note that this will introduce duplicates, unless the destination is using `overwrite-delete-stale` mode. Care should be taken to remove these duplicates after loading them. For more information, see [Managing Incremental Tables](/docs/advanced-topics/managing-incremental-tables).
87+
To enable this, `backend_options` must be set in the spec (as shown in the example config above). By default, incremental syncing is turned off. Also note that this will introduce duplicates, unless the destination is using `overwrite-delete-stale` mode. Care should be taken to remove these duplicates after loading them. For more information, see [Managing Incremental Tables](https://cloudquery.io/docs/advanced-topics/managing-incremental-tables).
8288

8389
## Example Queries
8490

@@ -172,7 +178,25 @@ make gen-docs
172178
### Release a new version
173179

174180
1. Run `git tag v1.0.0` to create a new tag for the release (replace `v1.0.0` with the new version number)
175-
2. Run `git push origin v1.0.0` to push the tag to GitHub
181+
2. Run `git push origin v1.0.0` to push the tag to GitHub
176182

177183
Once the tag is pushed, a new GitHub Actions workflow will be triggered to build the release binaries and create the new release on GitHub.
178184
To customize the release notes, see the Go releaser [changelog configuration docs](https://goreleaser.com/customization/changelog/#changelog).
185+
186+
### Publish a new version to the Cloudquery Hub
187+
188+
After tagging a release, you can build and publish a new version to the [Cloudquery Hub](https://hub.cloudquery.io/) by running the following commands.
189+
Replace `v1.0.0` with the new version number.
190+
191+
```bash
192+
# -m parameter adds release notes message, output is created in dist/ directory
193+
go run main.go package -m "Release v1.0.0" v1.0.0 .
194+
195+
# Login to cloudquery hub and publish the new version
196+
cloudquery login -t simple-analytics
197+
cloudquery plugin publish --finalize
198+
```
199+
200+
After publishing the new version, it will [show up](https://hub.cloudquery.io/plugins/source/simple-analytics/simple-analytics) in the [hub](https://hub.cloudquery.io/).
201+
202+
For more information please refer to the official [Publishing a Plugin to the Hub](https://cloudquery.io/docs/developers/publishing-a-plugin-to-the-hub) guide.

client/client.go

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
package client
22

33
import (
4-
"context"
5-
"fmt"
64
"strings"
75

8-
"github.com/cloudquery/cq-source-simple-analytics/internal/simpleanalytics"
9-
"github.com/cloudquery/plugin-sdk/backend"
10-
"github.com/cloudquery/plugin-sdk/plugins/source"
11-
"github.com/cloudquery/plugin-sdk/schema"
12-
"github.com/cloudquery/plugin-sdk/specs"
6+
"github.com/cloudquery/plugin-sdk/v4/state"
137
"github.com/rs/zerolog"
8+
"github.com/simpleanalytics/cq-source-simple-analytics/internal/simpleanalytics"
149
)
1510

1611
type Client struct {
1712
Logger zerolog.Logger
1813
SAClient *simpleanalytics.Client
19-
Backend backend.Backend
14+
Backend state.Client
2015
Spec Spec
2116
Website WebsiteSpec
2217
}
@@ -35,22 +30,11 @@ func (c *Client) withWebsite(website WebsiteSpec) *Client {
3530
}
3631
}
3732

38-
func New(_ context.Context, logger zerolog.Logger, s specs.Source, opts source.Options) (schema.ClientMeta, error) {
39-
var pluginSpec Spec
40-
if err := s.UnmarshalSpec(&pluginSpec); err != nil {
41-
return nil, fmt.Errorf("failed to unmarshal plugin spec: %w", err)
42-
}
43-
err := pluginSpec.Validate()
44-
if err != nil {
45-
return nil, fmt.Errorf("failed to validate plugin spec: %w", err)
46-
}
47-
pluginSpec.SetDefaults()
48-
49-
saClient := simpleanalytics.NewClient(pluginSpec.UserID, pluginSpec.APIKey)
33+
func New(logger zerolog.Logger, spec Spec, services *simpleanalytics.Client, bk state.Client) *Client {
5034
return &Client{
5135
Logger: logger,
52-
Backend: opts.Backend,
53-
Spec: pluginSpec,
54-
SAClient: saClient,
55-
}, nil
36+
SAClient: services,
37+
Backend: bk,
38+
Spec: spec,
39+
}
5640
}

client/multiplexers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package client
22

3-
import "github.com/cloudquery/plugin-sdk/schema"
3+
import "github.com/cloudquery/plugin-sdk/v4/schema"
44

55
func WebsiteMultiplex(meta schema.ClientMeta) []schema.ClientMeta {
66
var l = make([]schema.ClientMeta, 0)

client/spec.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ type Spec struct {
4141
// It is used to calculate start_time if it is not specified. If start_time is specified,
4242
// duration is ignored.
4343
PeriodStr string `json:"period"`
44+
45+
Concurrency int `json:"concurrency,omitempty"`
4446
}
4547

4648
type WebsiteSpec struct {
@@ -91,6 +93,9 @@ func (s *Spec) SetDefaults() {
9193
if s.EndDateStr == "" {
9294
s.EndDateStr = time.Now().Format(AllowedTimeLayout)
9395
}
96+
if s.Concurrency < 1 {
97+
s.Concurrency = 1000
98+
}
9499
}
95100

96101
func (s Spec) StartTime() time.Time {

client/testing.go

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,57 +7,48 @@ import (
77
"testing"
88
"time"
99

10-
"github.com/cloudquery/cq-source-simple-analytics/internal/simpleanalytics"
11-
"github.com/cloudquery/plugin-sdk/plugins/source"
12-
"github.com/cloudquery/plugin-sdk/schema"
13-
"github.com/cloudquery/plugin-sdk/specs"
10+
"github.com/cloudquery/plugin-sdk/v4/plugin"
11+
"github.com/cloudquery/plugin-sdk/v4/scheduler"
12+
"github.com/cloudquery/plugin-sdk/v4/schema"
13+
"github.com/cloudquery/plugin-sdk/v4/transformers"
1414
"github.com/rs/zerolog"
15+
"github.com/simpleanalytics/cq-source-simple-analytics/internal/simpleanalytics"
1516
)
1617

1718
func TestHelper(t *testing.T, table *schema.Table, ts *httptest.Server) {
18-
version := "vDev"
1919
table.IgnoreInTests = false
2020
t.Helper()
21+
2122
l := zerolog.New(zerolog.NewTestWriter(t)).Output(
2223
zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.StampMicro},
2324
).Level(zerolog.DebugLevel).With().Timestamp().Logger()
24-
newTestExecutionClient := func(ctx context.Context, logger zerolog.Logger, spec specs.Source, opts source.Options) (schema.ClientMeta, error) {
25-
saClient := simpleanalytics.NewClient("test", "test", simpleanalytics.WithBaseURL(ts.URL), simpleanalytics.WithHTTPClient(ts.Client()))
26-
s := Spec{
27-
UserID: "test",
28-
APIKey: "test",
29-
Websites: []WebsiteSpec{
30-
{
31-
Hostname: "test.com",
32-
MetadataFields: []string{"metadata_text", "metadata_int"},
33-
},
25+
sched := scheduler.NewScheduler(scheduler.WithLogger(l))
26+
27+
spec := &Spec{
28+
UserID: "test",
29+
APIKey: "test",
30+
Websites: []WebsiteSpec{
31+
{
32+
Hostname: "test.com",
33+
MetadataFields: []string{"metadata_text", "metadata_int"},
3434
},
35-
}
36-
s.SetDefaults()
37-
err := s.Validate()
38-
if err != nil {
39-
return nil, err
40-
}
41-
return &Client{
42-
Logger: l,
43-
SAClient: saClient,
44-
Backend: opts.Backend,
45-
Spec: s,
46-
}, nil
47-
}
48-
p := source.NewPlugin(
49-
table.Name,
50-
version,
51-
[]*schema.Table{
52-
table,
5335
},
54-
newTestExecutionClient)
55-
p.SetLogger(l)
56-
source.TestPluginSync(t, p, specs.Source{
57-
Name: "dev",
58-
Path: "cloudquery/dev",
59-
Version: version,
60-
Tables: []string{table.Name},
61-
Destinations: []string{"mock-destination"},
62-
})
36+
}
37+
spec.SetDefaults()
38+
if err := spec.Validate(); err != nil {
39+
t.Fatalf("failed to validate spec: %v", err)
40+
}
41+
42+
saClient := simpleanalytics.NewClient(spec.UserID, spec.APIKey, simpleanalytics.WithBaseURL(ts.URL), simpleanalytics.WithHTTPClient(ts.Client()))
43+
c := New(l, *spec, saClient, nil)
44+
45+
tables := schema.Tables{table}
46+
if err := transformers.TransformTables(tables); err != nil {
47+
t.Fatal(err)
48+
}
49+
messages, err := sched.SyncAll(context.Background(), c, tables)
50+
if err != nil {
51+
t.Fatalf("failed to sync: %v", err)
52+
}
53+
plugin.ValidateNoEmptyColumns(t, tables, messages)
6354
}

0 commit comments

Comments
 (0)