go-rel / rel

:gem: Modern ORM for Golang - Testable, Extendable and Crafted Into a Clean and Elegant API
https://go-rel.github.io/
MIT License
744 stars 58 forks source link

Extend Adapter interface to include function to return adapter name #345

Open lafriks opened 9 months ago

lafriks commented 9 months ago

Would be useful to allow check what adapter is used currently so that database type specific code could be executed only on right adapters.

func Name() string

or

func Type() string

that would return mysql, postgres, sqlite3 etc

Fs02 commented 9 months ago

could you give examples?

and is the database type specific code will be in sql package?

lafriks commented 9 months ago

no it's for usage in user code later on, for one I would want this to use in migrator package for such code to be able to lock down migrations so that if multiple instances are started at same time (for example in containers) they would not run same migrations:

    if m.typ == DatabaseSQLite3 {
        if err := m.sync(ctx); err != nil {
            cancelUpdate(err)
        }
        return func(ctx context.Context, vers int64) {
            if vers == 0 {
                return
            }
            if err := m.repo.Insert(ctx, &version{Version: vers}); err != nil {
                cancelUpdate(err)
            }
        }, func() {}
    }

    updZeroVersion := "INSERT INTO versions(version, created_at) VALUES (0, current_timestamp) ON CONFLICT(version) DO UPDATE SET updated_at = current_timestamp"
    if m.typ == DatabaseMySQL {
        updZeroVersion = "INSERT INTO versions(version, created_at) VALUES (0, current_timestamp) ON DUPLICATE KEY UPDATE updated_at = current_timestamp"
    }

currently because of that I have to copy over migrator code and can not really implement it upstream as instead of go-rel/migration package: https://github.com/go-rel/migration/blob/dbef2632dc4efecbb107b4c61648a0d0d255c0ac/migration.go#L170 I use:

// New migratorr.
func New(typ string, repo rel.Repository) *Migrator {
    return &Migrator{
        typ:  typ,
        repo: repo,
    }
}

instead I could use for db specific code something like m.repo.Adapter().Type() == "sqlite3" instead of having to keep around current database type in code and pass it all around for database type specific SQLs etc

Fs02 commented 9 months ago

got it, I think it's should be okay to add some metadata information like this

I prefer func Name() string, and maybe have a constant (ex: Name) in each adapter package so comparison can be done like: m.repo.Adapter().Type() == sqlite3.Name

lafriks commented 9 months ago

Ok, I will create PR

lafriks commented 9 months ago

@Fs02 please review: https://github.com/go-rel/rel/pull/346 https://github.com/go-rel/sql/pull/59 https://github.com/go-rel/sqlite3/pull/53

If naming/implementation looks good I will create PRs for other adapters

Fs02 commented 9 months ago

@lafriks need to be updated too https://github.com/go-rel/reltest/blob/main/nop_adapter.go https://github.com/go-rel/mssql