Skip to content

Instantly share code, notes, and snippets.

View jfeng45's full-sized avatar

Jin Feng jfeng45

View GitHub Profile
@jfeng45
jfeng45 / gdbc.go
Last active July 23, 2019 23:54
Wrapper for database access
// SqlGdbc (SQL Go database connection) is a wrapper for SQL database handler ( can be *sql.DB or *sql.Tx)
// It should be able to work with all SQL data that follows SQL standard.
type SqlGdbc interface {
Exec(query string, args ...interface{}) (sql.Result, error)
Prepare(query string) (*sql.Stmt, error)
Query(query string, args ...interface{}) (*sql.Rows, error)
QueryRow(query string, args ...interface{}) *sql.Row
// If need transaction support, add this interface
Transactioner
}
@jfeng45
jfeng45 / transaction.go
Last active July 23, 2019 12:27
transaction interface for database handler
// Transactioner is the transaction interface for database handler
// It should only be applicable to SQL database
type Transactioner interface {
// Rollback a transaction
Rollback() error
// Commit a transaction
Commit() error
// TxEnd commits a transaction if no errors, otherwise rollback
// txFunc is the operations wrapped in a transaction
TxEnd(txFunc func() error) error
@jfeng45
jfeng45 / txDataservice.go
Last active July 23, 2019 09:40
use case level transaction interface
// TxDataInterface represents operations needed for transaction support.
// It only needs to be implemented once for each database
// For sqlGdbc, it is implemented for SqlDBTx in transaction.go
type TxDataInterface interface {
// TxBegin starts a transaction. It gets a DB handler from the receiver and return a TxDataInterface, which has a
// *sql.Tx inside. Any data access wrapped inside a transaction will go through the *sql.Tx
TxBegin() (TxDataInterface, error)
// TxEnd is called at the end of a transaction and based on whether there is an error, it commits or rollback the
// transaction.
// txFunc is the business function wrapped in a transaction
@jfeng45
jfeng45 / registrationTransaction.go
Last active August 1, 2019 01:15
the business logic in transaction
// The use case of ModifyAndUnregister without transaction
func (ruc *RegistrationUseCase) ModifyAndUnregister(user *model.User) error {
return modifyAndUnregister(ruc, user)
}
// The use case of ModifyAndUnregister with transaction
func (ruc *RegistrationUseCase) ModifyAndUnregisterWithTx(user *model.User) error {
tdi, err := ruc.TxDataInterface.TxBegin()
if err != nil {
return errors.Wrap(err, "")
@jfeng45
jfeng45 / transactionBeginEnd.go
Last active July 23, 2019 12:23
transaction function in data handler layer
// TransactionBegin starts a transaction
func (sdt *SqlDBTx) TxBegin() (gdbc.SqlGdbc, error) {
tx, err := sdt.DB.Begin()
sct := SqlConnTx{tx}
return &sct, err
}
func (sct *SqlConnTx) TxEnd(txFunc func() error) error {
var err error
tx := sct.DB
@jfeng45
jfeng45 / logger.go
Created July 3, 2019 12:41
generic logger interface
// Log is a package level variable, every program should access logging function through "Log"
var Log Logger
// Logger represent common interface for logging function
type Logger interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
Fatal(args ...interface{})
Infof(format string, args ...interface{})
Info( args ...interface{})
@jfeng45
jfeng45 / zapWrapper.go
Last active July 3, 2019 13:45
wrapper for zap
type loggerWrapper struct {
lw *zap.SugaredLogger
}
func (logger *loggerWrapper) Errorf(format string, args ...interface{}) {
logger.lw.Errorf(format, args)
}
func (logger *loggerWrapper) Fatalf(format string, args ...interface{}) {
logger.lw.Fatalf(format, args)
}
func (logger *loggerWrapper) Fatal(args ...interface{}) {
@jfeng45
jfeng45 / sqlUserDataServiceFactory.go
Last active July 22, 2019 12:16
get cache factory from registry
// sqlUserDataServiceFactory is a empty receiver for Build method
type sqlUserDataServiceFactory struct{}
func (sudsf *sqlUserDataServiceFactory) Build(c container.Container, dataConfig *config.DataConfig)
(dataservice.UserDataInterface, error) {
dsc := dataConfig.DataStoreConfig
dsi, err := datastorefactory.GetDataStoreFb(dsc.Code).Build(c, &dsc)
if err != nil {
return nil, errors.Wrap(err, "")
@jfeng45
jfeng45 / databaseFactory.go
Last active July 25, 2019 12:05
database factory
// To map "database code" to "database interface builder"
// Concreate builder is in corresponding factory file. For example, "sqlFactory" is in "sqlFactory".go
var dsFbMap = map[string]dsFbInterface{
config.SQLDB: &sqlFactory{},
config.COUCHDB: &couchdbFactory{},
config.CACHE_GRPC: &cacheGrpcFactory{},
}
// DataStoreInterface serve as a marker to indicate the return type for Build method
type DataStoreInterface interface{}
@jfeng45
jfeng45 / mysqlFactory.go
Last active July 28, 2019 00:56
database factory for Mysql database
// sqlFactory is receiver for Build method
type sqlFactory struct{}
// implement Build method for SQL database
func (sf *sqlFactory) Build(c container.Container, dsc *config.DataStoreConfig) (DataStoreInterface, error) {
key := dsc.Code
//if it is already in container, return
if value, found := c.Get(key); found {
sdb := value.(*sql.DB)
sdt := databasehandler.SqlDBTx{DB: sdb}