Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dev/ci/go-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ echo "--- build libsqlite"
echo "--- comby install"
./dev/comby-install-or-upgrade.sh

# For code insights test
./dev/codeinsights-db.sh &
export CODEINSIGHTS_PGDATASOURCE=postgres://postgres:password@127.0.0.1:5435

# Separate out time for go mod from go test
echo "--- go mod download"
go mod download
Expand Down
5 changes: 3 additions & 2 deletions enterprise/internal/insights/insights.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ func Init(ctx context.Context, enterpriseServices *enterprise.Services) error {
// TimescaleDB in those deployments. https://github.com/sourcegraph/sourcegraph/issues/17218
return nil
}
_, err := initializeCodeInsightsDB()
timescale, err := initializeCodeInsightsDB()
if err != nil {
return err
}
enterpriseServices.InsightsResolver = resolvers.New()
postgres := dbconn.Global
enterpriseServices.InsightsResolver = resolvers.New(timescale, postgres)
return nil
}

Expand Down
17 changes: 13 additions & 4 deletions enterprise/internal/insights/resolvers/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ import (
"errors"

"github.com/sourcegraph/sourcegraph/cmd/frontend/graphqlbackend"
"github.com/sourcegraph/sourcegraph/enterprise/internal/campaigns/store"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/database/dbutil"
)

// Resolver is the GraphQL resolver of all things related to Insights.
type Resolver struct{}
type Resolver struct {
store *store.Store
settingStore *database.SettingStore
}

// New returns a new Resolver whose store uses the given database
func New() graphqlbackend.InsightsResolver {
return &Resolver{}
// New returns a new Resolver whose store uses the given Timescale and Postgres DBs.
func New(timescale, postgres dbutil.DB) graphqlbackend.InsightsResolver {
return &Resolver{
store: store.New(timescale),
settingStore: database.Settings(postgres),
}
}

func (r *Resolver) Insights(ctx context.Context) (graphqlbackend.InsightsResolver, error) {
Expand Down
12 changes: 12 additions & 0 deletions enterprise/internal/insights/store/insights_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package store

import (
"context"
"testing"
"time"
)

func testInsights(t *testing.T, ctx context.Context, s *Store, clock func() time.Time) {
// TODO: write tests against the store once it is implemented
// https://github.com/sourcegraph/sourcegraph/issues/17218
}
54 changes: 54 additions & 0 deletions enterprise/internal/insights/store/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package store

import (
"context"
"database/sql"
"os"
"os/user"
"strings"
"testing"

"github.com/sourcegraph/sourcegraph/internal/database/dbconn"
"github.com/sourcegraph/sourcegraph/internal/database/dbutil"
"github.com/sourcegraph/sourcegraph/internal/timeutil"
)

func TestIntegration(t *testing.T) {
if testing.Short() {
t.Skip()
}

t.Parallel()

getTimescaleDB := func(t testing.TB) *sql.DB {
// Setup TimescaleDB for testing.
username := ""
if user, err := user.Current(); err == nil {
username = user.Username
}
timescaleDSN := dbutil.PostgresDSN("codeinsights", username, os.Getenv)
db, err := dbconn.New(timescaleDSN, "insights-test-"+strings.Replace(t.Name(), "/", "_", -1))
if err != nil {
t.Log("")
t.Log("README: To run these tests you need to have the codeinsights TimescaleDB running:")
t.Log("")
t.Log("$ ./dev/codeinsights-db.sh &")
t.Log("$ export CODEINSIGHTS_PGDATASOURCE=postgres://postgres:password@127.0.0.1:5435")
t.Log("")
t.Log("Or skip them with 'go test -short'")
t.Log("")
t.Fatalf("Failed to connect to codeinsights database: %s", err)
}
if err := dbconn.MigrateDB(db, dbconn.CodeInsights); err != nil {
t.Fatalf("Failed to perform codeinsights database migration: %s", err)
}
return db
}

t.Run("Integration", func(t *testing.T) {
ctx := context.Background()
clock := timeutil.Now
store := NewWithClock(getTimescaleDB(t), clock)
t.Run("Insights", func(t *testing.T) { testInsights(t, ctx, store, clock) })
})
}
41 changes: 41 additions & 0 deletions enterprise/internal/insights/store/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package store

import (
"database/sql"
"time"

"github.com/sourcegraph/sourcegraph/internal/database/basestore"
"github.com/sourcegraph/sourcegraph/internal/database/dbutil"
"github.com/sourcegraph/sourcegraph/internal/timeutil"
)

// Store exposes methods to read and write code insights domain models from
// persistent storage.
type Store struct {
*basestore.Store
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

now func() time.Time
}

// New returns a new Store backed by the given Timescale db.
func New(db dbutil.DB) *Store {
return NewWithClock(db, timeutil.Now)
}

// NewWithClock returns a new Store backed by the given db and
// clock for timestamps.
func NewWithClock(db dbutil.DB, clock func() time.Time) *Store {
return &Store{Store: basestore.NewWithDB(db, sql.TxOptions{}), now: clock}
}

var _ basestore.ShareableStore = &Store{}

// Handle returns the underlying transactable database handle.
// Needed to implement the ShareableStore interface.
func (s *Store) Handle() *basestore.TransactableHandle { return s.Store.Handle() }

// With creates a new Store with the given basestore.Shareable store as the
// underlying basestore.Store.
// Needed to implement the basestore.Store interface
func (s *Store) With(other basestore.ShareableStore) *Store {
return &Store{Store: s.Store.With(other), now: s.now}
}