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

First aproach to new driver... reusing code... #21

Closed

Conversation

josejuanmontiel
Copy link

@josejuanmontiel josejuanmontiel commented Jan 28, 2023

The idea... include new driver reusing actual code... for later dinamically load by configuration.

With the two (three) actual driver ... use ifs inside actual backend... because new one of new drivers change the code more drastically, decide to implements new backend.

And to reuse actual code in backend that don't change... in this backend include the "parent" of sql backend (the actual one) and only reimplement those methods that didn't change.

The trick its done here

type csvqDBWriter struct {
sqlDBWriter
}

reusing the actual implementation ... and only change the method ... that realy change...

Comment on lines +40 to +41
dbTypeOracle = backends.DbTypeOracle
dbTypeCsvq = backends.DbTypeCsvq
Copy link
Author

Choose a reason for hiding this comment

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

New constants for the new drivers..

cmd/main.go Outdated
Comment on lines 31 to 34

// TODO - Adding drivers...
_ "github.com/mithrandie/csvq-driver" // sql.Open("csvq", "/path/to/data/directory")
_ "github.com/sijms/go-ora/v2" // sql.Open("oracle", "oracle://OT:yourpassword@localhost/XE")
Copy link
Author

Choose a reason for hiding this comment

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

Here add new drivers... only imports...

Comment on lines +194 to +195
case dbTypeCsvq:
backend, errI = backends.NewCsvqBackend(conn, opt, sLog)
Copy link
Author

Choose a reason for hiding this comment

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

Because with this driver... the code change a few... decide implement new backend .. this aproach (not use ifs with typo) could help later to load this code dinamically

@@ -22,4 +24,50 @@ type ResultSet interface {
WriteRow([]interface{}) error
Flush() error
Close() error
CreateTableSchema(cols []string, colTypes []*sql.ColumnType) insertSchema
Copy link
Author

Choose a reason for hiding this comment

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

This methods it a TODO may could be private as earlier...

Comment on lines +45 to +65
type SqlDB struct {
db *sql.DB
opt Opt
logger *log.Logger

// The result schemas (CREATE TABLE ...) are dynamically
// generated everytime queries are executed based on their result columns.
// They're cached here so as to avoid repetetive generation.
resTableSchemas map[string]insertSchema
schemaMutex sync.RWMutex
}

type Writer struct {
jobID string
taskName string
colsWritten bool
cols []string
rows [][]byte
tx *sql.Tx
tbl string
}
Copy link
Author

Choose a reason for hiding this comment

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

Move generic struct to interface... and other related things...

// They're cached here so as to avoid repetetive generation.
resTableSchemas map[string]insertSchema
schemaMutex sync.RWMutex
SqlDB
Copy link
Author

Choose a reason for hiding this comment

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

Use the generic type extacted to interface...

Comment on lines +21 to +22
Writer
SqlDB
Copy link
Author

Choose a reason for hiding this comment

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

Similar than before .. but less verbose :)

resTableSchemas: make(map[string]insertSchema),
schemaMutex: sync.RWMutex{},
logger: l,
SqlDB{
Copy link
Author

Choose a reason for hiding this comment

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

Use generic type...

backend: s,
tbl: fmt.Sprintf(s.opt.ResultsTable, jobID),
tx: tx,
Writer{
Copy link
Author

Choose a reason for hiding this comment

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

Use generic type...

Comment on lines +113 to +115
w.schemaMutex.RLock()
_, ok := w.resTableSchemas[w.taskName]
w.schemaMutex.RUnlock()
Copy link
Author

Choose a reason for hiding this comment

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

Now we dont nedd backend.. it's an aggreation..

Comment on lines +20 to +22
type csvqDBWriter struct {
sqlDBWriter
}
Copy link
Author

Choose a reason for hiding this comment

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

Here it's the tricky part ... this new backend implements the actual... but overwrite the only needed functionality...

return nil, err
}

return &csvqDBWriter{
Copy link
Author

Choose a reason for hiding this comment

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

Return it's own type of backend...

backends/csvq.go Outdated
Comment on lines 101 to 102
ins := fmt.Sprintf(`INSERT INTO "%%s" (%s) `, strings.Join(colNameHolder, ","))
ins += fmt.Sprintf("VALUES (%s)", strings.Join(colValHolder, ","))
Copy link
Author

Choose a reason for hiding this comment

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

The insert command change in csvq driver... and better than ifs... (as comented in other place) use a new backend...

backends/csvq.go Outdated
Comment on lines 136 to 139
// TODO - This should configurable... maybe in some case not supported or need incremental update..
// if _, err := tx.Exec(fmt.Sprintf(rSchema.dropTable, w.tbl)); err != nil {
// return err
// }
Copy link
Author

Choose a reason for hiding this comment

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

This driver don't need delete the table...

backends/csvq.go Outdated
Comment on lines 224 to 228
return insertSchema{
// TODO - In some dialects...
dropTable: `DROP TABLE IF EXISTS "%s";`,
createTable: fmt.Sprintf(`CREATE %s TABLE %%s (%s);`, unlogged, strings.Join(fields, ",")),
insertRow: fmt.Sprintf(`INSERT INTO %%s (%s) VALUES (%s)`, strings.Join(colNameHolder, ","), strings.Join(colValHolder, ",")),
Copy link
Author

Choose a reason for hiding this comment

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

And the sql change a little...

@knadh
Copy link
Collaborator

knadh commented Jan 31, 2023

Hi @josejuanmontiel. Thanks for the inline comments on the PR, but could you please explain here in a few bullet points, what exactly is changing, why, and how it helps. The overall architecture.

@josejuanmontiel
Copy link
Author

Hi!

  • What exactly is changing? There is an interface for the backends (before now, only one) the change consider this backend as parent backend to others, that only need to override the methods they change for new functionaly of this "driver"...

  • why? Splitting the new functionality to connect new database in different backend, organize the code better to future loading dinamically.

  • and how it helps? It could lead to remove the "if postgres" in some places ... if split the sql backend in two .. for mysql and postgres.

  • The overall architecture. To reuse the code in other backend need a few minor changes

  1. CreateTableSchema goes public to be called from jobber.go before w.RegisterColTypes(cols, colTypes)
  2. Move to the interfaces some types to organize
  3. Now types sqlDB and sqlDBWriter aggrete the fields, that leads to remove the name attribute backend *sqlDB from sqlDBWriter
  4. CreateTableSchema have the lock inside (not ouside)
  5. The new backend (csv) only implements the methods that have "sql code" that change in this database.

As bonus, need some extra configuration too... i include the comented option to run the jobber_test.go with testcontainer.

TODO:

  1. Adding some free CI ¿circleci?
  2. "Parametrizing" the it test with test container (adding // +build integration)
  3. Adding some test for the new csvq driver

@josejuanmontiel josejuanmontiel marked this pull request as ready for review February 9, 2023 22:37
@josejuanmontiel josejuanmontiel changed the title WIP First aproach to new driver... reusing code... First aproach to new driver... reusing code... Feb 9, 2023
@knadh
Copy link
Collaborator

knadh commented Feb 10, 2023

Thanks for the update. Will try to review this some time soon.

@knadh
Copy link
Collaborator

knadh commented Sep 22, 2023

Please see this #23 (comment)

@knadh knadh closed this Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants