2020-06-16 15:15:04 +03:00
|
|
|
package seed
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
2022-10-26 09:01:02 +03:00
|
|
|
internalerrors "github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
2021-06-16 14:44:15 +03:00
|
|
|
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
|
2021-04-01 13:38:55 +03:00
|
|
|
|
2021-06-16 14:44:15 +03:00
|
|
|
"github.com/hasura/graphql-engine/cli/v2"
|
2020-06-16 15:15:04 +03:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
|
|
|
|
"github.com/spf13/afero"
|
|
|
|
)
|
|
|
|
|
2021-04-01 13:38:55 +03:00
|
|
|
func hasAllowedSeedFileExtensions(filename string) error {
|
2022-10-26 09:01:02 +03:00
|
|
|
var op internalerrors.Op = "seed.hasAllowedSeedFileExtensions"
|
2021-04-01 13:38:55 +03:00
|
|
|
extension := filepath.Ext(filename)
|
|
|
|
allowedExtensions := []string{".sql", ".SQL"}
|
|
|
|
for _, allowedExtension := range allowedExtensions {
|
|
|
|
if allowedExtension == extension {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, fmt.Errorf("expected extension to be one of %v but got %s on file %s", allowedExtensions, extension, filename))
|
2021-04-01 13:38:55 +03:00
|
|
|
}
|
|
|
|
|
2020-06-16 15:15:04 +03:00
|
|
|
// ApplySeedsToDatabase will read all .sql files in the given
|
|
|
|
// directory and apply it to hasura
|
2021-04-01 13:38:55 +03:00
|
|
|
func (d *Driver) ApplySeedsToDatabase(fs afero.Fs, rootSeedsDirectory string, filenames []string, source cli.Source) error {
|
2022-10-26 09:01:02 +03:00
|
|
|
var op internalerrors.Op = "seed.Driver.ApplySeedsToDatabase"
|
2021-04-01 13:38:55 +03:00
|
|
|
seedsDirectory := rootSeedsDirectory
|
|
|
|
if len(source.Name) > 0 {
|
|
|
|
seedsDirectory = filepath.Join(rootSeedsDirectory, source.Name)
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
getSourceKind := func(source cli.Source) hasura.SourceKind {
|
|
|
|
if len(source.Name) == 0 {
|
|
|
|
return hasura.SourceKindPG
|
|
|
|
}
|
|
|
|
return source.Kind
|
|
|
|
}
|
|
|
|
var sqlAsBytes [][]byte
|
2020-06-16 15:15:04 +03:00
|
|
|
if len(filenames) > 0 {
|
|
|
|
for _, filename := range filenames {
|
2021-04-01 13:38:55 +03:00
|
|
|
absFilename := filepath.Join(seedsDirectory, filename)
|
|
|
|
if err := hasAllowedSeedFileExtensions(absFilename); err != nil {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, err)
|
2021-04-01 13:38:55 +03:00
|
|
|
}
|
2020-06-16 15:15:04 +03:00
|
|
|
b, err := afero.ReadFile(fs, absFilename)
|
|
|
|
if err != nil {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, errors.Wrap(err, "error opening file"))
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
sqlAsBytes = append(sqlAsBytes, b)
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
|
|
|
} else {
|
2021-04-01 13:38:55 +03:00
|
|
|
err := afero.Walk(fs, seedsDirectory, func(path string, file os.FileInfo, err error) error {
|
2020-06-16 15:15:04 +03:00
|
|
|
if file == nil || err != nil {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, err)
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
if err := hasAllowedSeedFileExtensions(file.Name()); err == nil && !file.IsDir() {
|
2020-06-16 15:15:04 +03:00
|
|
|
b, err := afero.ReadFile(fs, path)
|
|
|
|
if err != nil {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, errors.Wrap(err, "error opening file"))
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
sqlAsBytes = append(sqlAsBytes, b)
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, errors.Wrap(err, "error walking the directory path"))
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
var args []hasura.RequestBody
|
|
|
|
sourceKind := getSourceKind(source)
|
|
|
|
switch sourceKind {
|
|
|
|
case hasura.SourceKindPG:
|
|
|
|
for _, sql := range sqlAsBytes {
|
|
|
|
request := hasura.RequestBody{
|
|
|
|
Type: "run_sql",
|
|
|
|
Args: hasura.PGRunSQLInput{
|
|
|
|
SQL: string(sql),
|
|
|
|
Source: source.Name,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
args = append(args, request)
|
|
|
|
}
|
|
|
|
case hasura.SourceKindMSSQL:
|
|
|
|
for _, sql := range sqlAsBytes {
|
|
|
|
request := hasura.RequestBody{
|
|
|
|
Type: "mssql_run_sql",
|
|
|
|
Args: hasura.MSSQLRunSQLInput{
|
|
|
|
SQL: string(sql),
|
|
|
|
Source: source.Name,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
args = append(args, request)
|
|
|
|
}
|
2021-06-21 17:34:10 +03:00
|
|
|
case hasura.SourceKindCitus:
|
|
|
|
for _, sql := range sqlAsBytes {
|
|
|
|
request := hasura.RequestBody{
|
|
|
|
Type: "citus_run_sql",
|
|
|
|
Args: hasura.CitusRunSQLInput{
|
|
|
|
SQL: string(sql),
|
|
|
|
Source: source.Name,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
args = append(args, request)
|
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
default:
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, fmt.Errorf("database %s of kind %s is not supported", source.Name, source.Kind))
|
2021-04-01 13:38:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(args) == 0 {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, fmt.Errorf("no SQL files found in %s", seedsDirectory))
|
2021-04-01 13:38:55 +03:00
|
|
|
}
|
|
|
|
_, err := d.SendBulk(args)
|
|
|
|
if err != nil {
|
2022-10-26 09:01:02 +03:00
|
|
|
return internalerrors.E(op, err)
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|
2021-04-01 13:38:55 +03:00
|
|
|
return nil
|
2020-06-16 15:15:04 +03:00
|
|
|
}
|