Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/227 #229

Merged
merged 88 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from 87 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
3b391cd
Fixed #205: Removed default projection as the default event listener
akeemphilbert Jul 28, 2022
c96e60c
Merge branch 'dev' into feature/205
akeemphilbert Aug 6, 2022
67de3d3
Fixed #198: Added EntityRepository interface
akeemphilbert Aug 6, 2022
93a6165
Fixed #209: Setup basic default write controller
akeemphilbert Aug 6, 2022
e6a8594
Fixed #209: Added DefaultReadController
akeemphilbert Aug 7, 2022
1abdb57
Merge branch 'feature/205' into feature/210
akeemphilbert Aug 7, 2022
68d1ff3
wip #210: Update command dispatcher interface
akeemphilbert Aug 7, 2022
9693ce1
wip #209: Updated controller signature so that the operation is a map…
akeemphilbert Aug 7, 2022
edd068d
Merge branch 'feature/209' into feature/210
akeemphilbert Aug 7, 2022
2a6a001
feature #210: Pass EntityRepository to Command Receivers
akeemphilbert Aug 7, 2022
b7a646f
feature #205: Updated command receivers
akeemphilbert Aug 7, 2022
3aa122b
feature #205: Updated EntityFactoryInitializer to be EntityRepository…
akeemphilbert Aug 8, 2022
d460b27
feature: #209 Add Default Controllers
akeemphilbert Aug 11, 2022
506859a
feature: #209 Fixed issue where endpoint without schema threw error
akeemphilbert Aug 12, 2022
3dab4d5
feature: #209 Added code to render templates response
akeemphilbert Aug 12, 2022
ff17f52
feature: #209 Added huge workaround that hardcodes static serving to /
akeemphilbert Aug 12, 2022
9454910
feature: #209 Added code to render templates if configured
akeemphilbert Aug 12, 2022
49b63ee
feature: #209 Updated to export error message in json
akeemphilbert Aug 12, 2022
2781d61
feature: #209 Updated to export error message in json
akeemphilbert Aug 12, 2022
e5b1afb
feature: #209 Fix for serving static on a sub path
akeemphilbert Aug 13, 2022
1e817d8
feature: #194 Added x-inline extension to mark schema as inline
akeemphilbert Aug 15, 2022
38bf908
feature: #194 attempted fix for model parsing during startup (project…
akeemphilbert Aug 15, 2022
d137f5e
feature: #194 added test to confirm that migration should work
akeemphilbert Aug 15, 2022
9780380
feature: #194 if inline error is returned move to the next one during…
akeemphilbert Aug 15, 2022
15efee2
feature: #194 iremoved ignoring of inline schema error (this is neede…
akeemphilbert Aug 15, 2022
84dc4aa
feature: #194 return error (and not a custom error)
akeemphilbert Aug 15, 2022
f8ea629
feature: #194 fix issue with parsing incoming data
akeemphilbert Aug 16, 2022
edd7302
feature: #194 fix issue with parsing incoming data
akeemphilbert Aug 16, 2022
2c69316
feature: #194 Got entity with inline schemas saving
akeemphilbert Aug 16, 2022
ab58a21
Merge branch 'dev' into feature/194
akeemphilbert Aug 23, 2022
5897f30
feature: #194 Fixed issue where associated models were not being retu…
akeemphilbert Aug 23, 2022
6ae69f3
feature: #194 #209 Test Fixes
akeemphilbert Aug 23, 2022
ebdbcfc
feature: #209 Added path to the controller function interface to bene…
akeemphilbert Aug 25, 2022
839a2a3
feature: #209 Fixed controllers tests to match updated signature
akeemphilbert Aug 27, 2022
df6eeb8
feature: #218 Add global initializer for entity repositories
akeemphilbert Aug 27, 2022
f541368
feature: #209 Made it so that if the accept header is empty return em…
akeemphilbert Aug 27, 2022
62dc438
Merge branch 'feature/209' into feature/218
akeemphilbert Aug 27, 2022
ed1b729
fix: Switched to using entity repository
akeemphilbert Aug 28, 2022
52b277b
Merge branch 'feature/209' into feature/218
akeemphilbert Aug 28, 2022
aa2ada2
fix: Added nil check before converting form request to json
akeemphilbert Aug 28, 2022
f02152c
fix: Made it so that error is returned on DefaultWriteController so t…
akeemphilbert Aug 28, 2022
67ef537
Merge branch 'feature/209' into feature/218
akeemphilbert Aug 28, 2022
53caa6a
feature: #209 Made it so that the DefaultWriteController is used when…
akeemphilbert Aug 29, 2022
3f37ae3
Merge branch 'feature/209' into feature/218
akeemphilbert Aug 29, 2022
b3062a4
feature: #209 Return the command response with a status ok by default
akeemphilbert Aug 29, 2022
73d2487
fix: issue where entity didn't have a reference to the name
akeemphilbert Aug 29, 2022
2a9bf4f
fix: path method didn't match
akeemphilbert Aug 30, 2022
6e37fa3
fix: path method didn't match
akeemphilbert Sep 7, 2022
e2fa7e3
fix: id not being set on read controlelr
akeemphilbert Sep 7, 2022
716d494
Merge branch 'feature/209' into feature/218
akeemphilbert Sep 7, 2022
6d72929
fix: id not being set on read controlelr
akeemphilbert Sep 7, 2022
5a0e2b6
Merge branch 'feature/209' into feature/218
akeemphilbert Sep 7, 2022
bc3886f
fix: id not being set on read controlelr
akeemphilbert Sep 7, 2022
bf4291c
feature #222 Remove unique requirement on weos id
akeemphilbert Sep 13, 2022
0404643
feature #209 Fix issue where autoConfigure was not being set to true …
akeemphilbert Sep 16, 2022
e88cc43
feature #209 wrapped list logic in a check for existance of an entity…
akeemphilbert Sep 16, 2022
aa42875
Merge branch 'feature/218' into feature/222
akeemphilbert Sep 17, 2022
90fd8c5
feature #223 fix primary key comparison issues by checking to see if …
akeemphilbert Sep 20, 2022
e1c8f37
feature #223 fix issue where sort key was not being used
akeemphilbert Sep 20, 2022
e87c141
feature #223 added more comparison operators
akeemphilbert Sep 20, 2022
b6b211e
feature #218 If x-templates is set on a get request use the read cont…
akeemphilbert Sep 22, 2022
1429248
include stack trace when outputting command handler error
akeemphilbert Oct 2, 2022
cf96273
include stack trace when outputting command handler error
akeemphilbert Oct 2, 2022
49dd3f2
add support for odbc connection
akeemphilbert Oct 3, 2022
6b1e77f
feature: #224 Started setting up table alias code
akeemphilbert Oct 3, 2022
00c994c
feature: #224 import odbc library as a side import
akeemphilbert Oct 10, 2022
1d162bf
feature: #224 put back in username and password in the connection string
akeemphilbert Oct 10, 2022
2ffc767
feature: #224 added log line
akeemphilbert Oct 10, 2022
578c9e0
feature: #224 added log line
akeemphilbert Oct 12, 2022
4dad3c2
feature: #224 this is for the benefit of the iSeries connection
akeemphilbert Oct 12, 2022
a7857a8
feature: #224 Bump the git version no. for weos and debugging reasons
akeemphilbert Oct 25, 2022
15403b8
feature: #224 Fix for is entity repository is null
akeemphilbert Oct 28, 2022
0bc1c71
feature: #224 Add token to error message when parsing jwt fails
akeemphilbert Nov 23, 2022
2449950
feature: #224 Fix for is entity repository is null
akeemphilbert Oct 28, 2022
92e26c7
feature: #224 Add token to error message when parsing jwt fails
akeemphilbert Nov 23, 2022
2f2dd45
Merge remote-tracking branch 'origin/feature/224' into feature/224
akeemphilbert Nov 23, 2022
c32bb50
Revert "feature: #224 this is for the benefit of the iSeries connection"
akeemphilbert Nov 23, 2022
a46c1fb
Revert "feature: #224 added log line"
akeemphilbert Nov 23, 2022
9e60cf2
Revert "feature: #224 added log line"
akeemphilbert Nov 23, 2022
4feaf8c
Revert "feature: #224 put back in username and password in the connec…
akeemphilbert Nov 23, 2022
79771f8
Revert "feature: #224 import odbc library as a side import"
akeemphilbert Nov 23, 2022
f2e581f
Revert "feature: #224 Started setting up table alias code"
akeemphilbert Nov 23, 2022
753ed2b
Revert "add support for odbc connection"
akeemphilbert Nov 23, 2022
cb3f3e5
feature: #224 Added all headers to error message
akeemphilbert Nov 23, 2022
fde552b
feature: #224 fix issue where security enforcer was not working when …
akeemphilbert Nov 23, 2022
29b888d
feature: #227 Added tests for the IAM functionality
akeemphilbert Jan 13, 2023
25f97e9
feature #227: updated the SQLConnectionFromConfig function to connect…
IshikaGopie Jan 13, 2023
0d1a631
feature #227: updated connection string to include the parameters tha…
IshikaGopie Jan 17, 2023
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
2 changes: 2 additions & 0 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ const REQUEST_ID ContextKey = "REQUEST_ID"
const WEOS_ID ContextKey = "WEOS_ID"
const CONTENT_TYPE ContextKey = "_contentType"
const ENTITY_FACTORY ContextKey = "_entityFactory"
const ENTITY_REPOSITORY ContextKey = "_entityRepository"
const MIDDLEWARES ContextKey = "_middlewares"
const CONTROLLER ContextKey = "_controller"
const PROJECTION ContextKey = "_projection"
const PROJECTIONS ContextKey = "_projections"
const REPOSITORY = "_repository"
const COMMAND_DISPATCHER ContextKey = "_command_disptacher"
const EVENT_STORE ContextKey = "_event_store"
const SCHEMA_BUILDERS ContextKey = "_schema_builders"
Expand Down
190 changes: 107 additions & 83 deletions controllers/rest/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"database/sql"
"errors"
"fmt"
awsconfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/rds/auth"
"github.com/casbin/casbin/v2"
"net/http"
"os"
Expand All @@ -31,12 +33,13 @@ import (
"github.com/wepala/weos/projections"
)

var InvalidAWSDriver = errors.New("invalid aws driver specified, must be postgres or mysql")

//RESTAPI is used to manage the API
type RESTAPI struct {
Application model.Service
Log model.Log
DB *sql.DB
Client *http.Client
projection *projections.GORMDB
Config *APIConfig
securityConfiguration *SecurityConfiguration
Expand All @@ -48,7 +51,7 @@ type RESTAPI struct {
controllers map[string]Controller
eventStores map[string]model.EventRepository
commandDispatchers map[string]model.CommandDispatcher
projections map[string]projections.Projection
projections map[string]model.Projection
logs map[string]model.Log
httpClients map[string]*http.Client
globalInitializers []GlobalInitializer
Expand All @@ -62,13 +65,7 @@ type RESTAPI struct {
dbConnections map[string]*sql.DB
gormConnections map[string]*gorm.DB
enforcers map[string]*casbin.Enforcer
}

type schema struct {
Name string
Type string
Ref string
Properties []schema
entityRepositories map[string]model.EntityRepository
}

//define an interface that all plugins must implement
Expand Down Expand Up @@ -195,7 +192,7 @@ func (p *RESTAPI) RegisterCommandDispatcher(name string, dispatcher model.Comman
//RegisterProjection Add command dispatcher so that it can be referenced in the OpenAPI spec
func (p *RESTAPI) RegisterProjection(name string, projection model.Projection) {
if p.projections == nil {
p.projections = make(map[string]projections.Projection)
p.projections = make(map[string]model.Projection)
}
p.projections[name] = projection
}
Expand Down Expand Up @@ -249,7 +246,7 @@ func (p *RESTAPI) GetMiddleware(name string) (Middleware, error) {
tmiddleware := t.MethodByName(name)
//only show error if handler was set
if tmiddleware.IsValid() {
return tmiddleware.Interface().(func(api Container, projection projections.Projection, commandDispatcher model.CommandDispatcher, eventSource model.EventRepository, entityFactory model.EntityFactory, path *openapi3.PathItem, operation *openapi3.Operation) echo.MiddlewareFunc), nil
return tmiddleware.Interface().(func(api Container, commandDispatcher model.CommandDispatcher, repository model.EntityRepository, path *openapi3.PathItem, operation *openapi3.Operation) echo.MiddlewareFunc), nil
}

return nil, fmt.Errorf("middleware '%s' not found", name)
Expand All @@ -266,7 +263,7 @@ func (p *RESTAPI) GetController(name string) (Controller, error) {
tcontroller := t.MethodByName(name)
//only show error if handler was set
if tcontroller.IsValid() {
return tcontroller.Interface().(func(api Container, projection projections.Projection, commandDispatcher model.CommandDispatcher, eventSource model.EventRepository, entityFactory model.EntityFactory) echo.HandlerFunc), nil
return tcontroller.Interface().(func(api Container, commandDispatcher model.CommandDispatcher, repository model.EntityRepository, pathMap map[string]*openapi3.PathItem, operation map[string]*openapi3.Operation) echo.HandlerFunc), nil
}

return nil, fmt.Errorf("controller '%s' not found", name)
Expand Down Expand Up @@ -296,6 +293,20 @@ func (p *RESTAPI) GetProjection(name string) (model.Projection, error) {
return nil, fmt.Errorf("projection '%s' not found", name)
}

func (p *RESTAPI) RegisterEntityRepository(name string, repository model.EntityRepository) {
if p.entityRepositories == nil {
p.entityRepositories = make(map[string]model.EntityRepository)
}
p.entityRepositories[name] = repository
}

func (p *RESTAPI) GetEntityRepository(name string) (model.EntityRepository, error) {
if trepository, ok := p.entityRepositories[name]; ok {
return trepository, nil
}
return nil, fmt.Errorf("entity repository '%s' not found", name)
}

//GetGlobalInitializers get global intializers in the order they were registered
func (p *RESTAPI) GetGlobalInitializers() []GlobalInitializer {
return p.globalInitializers
Expand Down Expand Up @@ -436,38 +447,26 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
Timeout: time.Second * 10,
})
//register standard controllers
p.RegisterController("CreateController", CreateController)
p.RegisterController("UpdateController", UpdateController)
p.RegisterController("ListController", ListController)
p.RegisterController("ViewController", ViewController)
p.RegisterController("DeleteController", DeleteController)
p.RegisterController("HealthCheck", HealthCheck)
p.RegisterController("CreateBatchController", CreateBatchController)
p.RegisterController("APIDiscovery", APIDiscovery)
p.RegisterController("DefaultResponseController", DefaultResponseController)
p.RegisterController("DefaultWriteController", DefaultWriteController)
p.RegisterController("DefaultReadController", DefaultReadController)
p.RegisterController("DefaultListController", DefaultListController)

//register standard middleware
p.RegisterMiddleware("Context", Context)
p.RegisterMiddleware("CreateMiddleware", CreateMiddleware)
p.RegisterMiddleware("CreateBatchMiddleware", CreateBatchMiddleware)
p.RegisterMiddleware("UpdateMiddleware", UpdateMiddleware)
p.RegisterMiddleware("ListMiddleware", ListMiddleware)
p.RegisterMiddleware("ViewMiddleware", ViewMiddleware)
p.RegisterMiddleware("DeleteMiddleware", DeleteMiddleware)
p.RegisterMiddleware("Recover", Recover)
p.RegisterMiddleware("ContentTypeResponseMiddleware", ContentTypeResponseMiddleware)
p.RegisterMiddleware("DefaultResponseMiddleware", DefaultResponseMiddleware)
p.RegisterMiddleware("LogLevel", LogLevel)
p.RegisterMiddleware("ZapLogger", ZapLogger)
//register standard global initializers
p.RegisterGlobalInitializer(SQLDatabase)
p.RegisterGlobalInitializer(DefaultProjection)
p.RegisterGlobalInitializer(RegisterEntityRepositories)
p.RegisterGlobalInitializer(DefaultEventStore)
p.RegisterGlobalInitializer(Security)
//register standard operation initializers
p.RegisterOperationInitializer(ContextInitializer)
p.RegisterOperationInitializer(ContentTypeResponseInitializer)
p.RegisterOperationInitializer(EntityFactoryInitializer)
p.RegisterOperationInitializer(EntityRepositoryInitializer)
p.RegisterOperationInitializer(UserDefinedInitializer)
p.RegisterOperationInitializer(AuthorizationInitializer)
p.RegisterOperationInitializer(StandardInitializer)
Expand All @@ -480,9 +479,8 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
defaultCommandDispatcher := &model.DefaultCommandDispatcher{}
//setup default commands
defaultCommandDispatcher.AddSubscriber(model.Create(context.Background(), nil, "", ""), model.CreateHandler)
defaultCommandDispatcher.AddSubscriber(model.CreateBatch(context.Background(), nil, ""), model.CreateBatchHandler)
defaultCommandDispatcher.AddSubscriber(model.Update(context.Background(), nil, ""), model.UpdateHandler)
defaultCommandDispatcher.AddSubscriber(model.Delete(context.Background(), "", ""), model.DeleteHandler)
defaultCommandDispatcher.AddSubscriber(model.Delete(context.Background(), "", "", 0), model.DeleteHandler)
p.RegisterCommandDispatcher("Default", defaultCommandDispatcher)
}

Expand Down Expand Up @@ -515,13 +513,6 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
//}
//all routes setup after this will use this middleware
p.e.Use(middlewares...)

//initialize app
if p.Client == nil {
p.Client = &http.Client{
Timeout: time.Second * 10,
}
}
//set log level to debug
p.EchoInstance().Logger.SetLevel(log.DEBUG)

Expand Down Expand Up @@ -575,56 +566,89 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
}

//SQLConnectionFromConfig get db connection based on a Config
func (p *RESTAPI) SQLConnectionFromConfig(config *model.DBConfig) (*sql.DB, *gorm.DB, error) {
func (p *RESTAPI) SQLConnectionFromConfig(config *model.DBConfig) (*sql.DB, *gorm.DB, string, error) {
var connStr string
var err error

switch config.Driver {
case "sqlite3":
//check if file exists and if not create it. We only do this if a memory only db is NOT asked for
//(Note that if it's a combination we go ahead and create the file) https://www.sqlite.org/inmemorydb.html
if config.Database != ":memory:" {
if _, err = os.Stat(config.Database); os.IsNotExist(err) {
_, err = os.Create(strings.Replace(config.Database, ":memory:", "", -1))
if err != nil {
return nil, nil, model.NewError(fmt.Sprintf("error creating sqlite database '%s'", config.Database), err)
if config.AwsIam {
dbName := config.Database
dbUser := config.User
dbHost := config.Host
dbPort := config.Port
dbEndpoint := fmt.Sprintf("%s:%d", dbHost, dbPort)
region := config.AwsRegion

cfg, err := awsconfig.LoadDefaultConfig(context.TODO())
if err != nil {
log.Printf("aws configuration error: " + err.Error())
}

authenticationToken, err := auth.BuildAuthToken(
context.TODO(), dbEndpoint, region, dbUser, cfg.Credentials)
if err != nil {
log.Printf("failed to create aws authentication token: " + err.Error())
}

switch config.Driver {
case "mysql":
connStr = fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true&allowCleartextPasswords=true",
Copy link
Contributor

Choose a reason for hiding this comment

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

you're essentially creating your own connection string for mysql but it doesn't account for the parameters that are needed to get the mysql stuff working with GORM see the mysql connection string connStr = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&parseTime=true",

dbUser, authenticationToken, dbEndpoint, dbName,
)
case "postgres":
connStr = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s",
dbHost, dbPort, dbUser, authenticationToken, dbName,
)
default:
return nil, nil, "", InvalidAWSDriver
}
} else {
switch config.Driver {
case "sqlite3":
//check if file exists and if not create it. We only do this if a memory only db is NOT asked for
//(Note that if it's a combination we go ahead and create the file) https://www.sqlite.org/inmemorydb.html
if config.Database != ":memory:" {
if _, err = os.Stat(config.Database); os.IsNotExist(err) {
_, err = os.Create(strings.Replace(config.Database, ":memory:", "", -1))
if err != nil {
return nil, nil, "", model.NewError(fmt.Sprintf("error creating sqlite database '%s'", config.Database), err)
}
}
}
}

connStr = fmt.Sprintf("%s",
config.Database)
connStr = fmt.Sprintf("%s",
config.Database)

//update connection string to include authentication IF a username is set
if config.User != "" {
authenticationString := fmt.Sprintf("?_auth&_auth_user=%s&_auth_pass=%s&_auth_crypt=sha512&_foreign_keys=on",
config.User, config.Password)
connStr = connStr + authenticationString
} else {
connStr = connStr + "?_foreign_keys=on"
//update connection string to include authentication IF a username is set
if config.User != "" {
authenticationString := fmt.Sprintf("?_auth&_auth_user=%s&_auth_pass=%s&_auth_crypt=sha512&_foreign_keys=on",
config.User, config.Password)
connStr = connStr + authenticationString
} else {
connStr = connStr + "?_foreign_keys=on"
}
log.Debugf("sqlite connection string '%s'", connStr)
case "sqlserver":
connStr = fmt.Sprintf("sqlserver://%s:%s@%s:%s/%s",
config.User, config.Password, config.Host, strconv.Itoa(config.Port), config.Database)
case "ramsql":
connStr = "Testing"
case "mysql":
connStr = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&parseTime=true",
config.User, config.Password, config.Host, strconv.Itoa(config.Port), config.Database)
case "clickhouse":
connStr = fmt.Sprintf("tcp://%s:%s?username=%s&password=%s&database=%s",
config.Host, strconv.Itoa(config.Port), config.User, config.Password, config.Database)
case "postgres":
connStr = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
config.Host, strconv.Itoa(config.Port), config.User, config.Password, config.Database)
default:
return nil, nil, connStr, errors.New(fmt.Sprintf("db driver '%s' is not supported ", config.Driver))
}
log.Debugf("sqlite connection string '%s'", connStr)
case "sqlserver":
connStr = fmt.Sprintf("sqlserver://%s:%s@%s:%s/%s",
config.User, config.Password, config.Host, strconv.Itoa(config.Port), config.Database)
case "ramsql":
connStr = "Testing"
case "mysql":
connStr = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'&parseTime=true",
config.User, config.Password, config.Host, strconv.Itoa(config.Port), config.Database)
case "clickhouse":
connStr = fmt.Sprintf("tcp://%s:%s?username=%s&password=%s&database=%s",
config.Host, strconv.Itoa(config.Port), config.User, config.Password, config.Database)
case "postgres":
connStr = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
config.Host, strconv.Itoa(config.Port), config.User, config.Password, config.Database)
default:
return nil, nil, errors.New(fmt.Sprintf("db driver '%s' is not supported ", config.Driver))
}

db, err := sql.Open(config.Driver, connStr)
if err != nil {
return nil, nil, errors.New(fmt.Sprintf("error setting up connection to database '%s' with connection '%s'", err, connStr))
return nil, nil, connStr, errors.New(fmt.Sprintf("error setting up connection to database '%s' with connection '%s'", err, connStr))
}

db.SetMaxOpenConns(config.MaxOpen)
Expand All @@ -638,7 +662,7 @@ func (p *RESTAPI) SQLConnectionFromConfig(config *model.DBConfig) (*sql.DB, *gor
Conn: db,
}), nil)
if err != nil {
return nil, nil, err
return nil, nil, connStr, err
}
case "sqlite3":
gormDB, err = gorm.Open(&dialects.SQLite{
Expand All @@ -647,14 +671,14 @@ func (p *RESTAPI) SQLConnectionFromConfig(config *model.DBConfig) (*sql.DB, *gor
},
}, nil)
if err != nil {
return nil, nil, err
return nil, nil, connStr, err
}
case "mysql":
gormDB, err = gorm.Open(dialects.NewMySQL(mysql.Config{
Conn: db,
}), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true})
if err != nil {
return nil, nil, err
return nil, nil, connStr, err
}
case "ramsql": //this is for testing
gormDB = &gorm.DB{}
Expand All @@ -663,17 +687,17 @@ func (p *RESTAPI) SQLConnectionFromConfig(config *model.DBConfig) (*sql.DB, *gor
Conn: db,
}), nil)
if err != nil {
return nil, nil, err
return nil, nil, connStr, err
}
case "clickhouse":
gormDB, err = gorm.Open(clickhouse.New(clickhouse.Config{
Conn: db,
}), nil)
if err != nil {
return nil, nil, err
return nil, nil, connStr, err
}
default:
return nil, nil, errors.New(fmt.Sprintf("we don't support database driver '%s'", config.Driver))
return nil, nil, connStr, errors.New(fmt.Sprintf("we don't support database driver '%s'", config.Driver))
}
return db, gormDB, err
return db, gormDB, connStr, err
}
Loading