github.com/mantzas/incata@v0.3.0/storage/storage.go (about)

     1  package storage
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  // DbType defines the type of the db
    10  type DbType int
    11  
    12  // Relational Db Types
    13  const (
    14  	MSSQL      DbType = iota // MS SQL Server
    15  	PostgreSQL               // Postgresql
    16  )
    17  
    18  var dbTypeMap = map[string]DbType{
    19  	"mssql":      MSSQL,
    20  	"postgresql": PostgreSQL,
    21  }
    22  
    23  // ConvertToDbType convert's a string to a DbType
    24  func ConvertToDbType(value string) (DbType, error) {
    25  
    26  	dbType, ok := dbTypeMap[strings.ToLower(value)]
    27  
    28  	if ok {
    29  		return dbType, nil
    30  	}
    31  
    32  	return 0, fmt.Errorf("Failed to convert %s to db type", value)
    33  }
    34  
    35  // Storage a db abstraction
    36  type Storage struct {
    37  	innerDb                   *sql.DB
    38  	DbType                    DbType
    39  	AppendStatement           string
    40  	SelectBySourceIDStatement string
    41  }
    42  
    43  // Exec executes sql statement
    44  func (db *Storage) Exec(query string, args ...interface{}) (*sql.Result, error) {
    45  	result, err := db.innerDb.Exec(query, args...)
    46  	return &result, err
    47  }
    48  
    49  // Query executes a query statement
    50  func (db *Storage) Query(query string, args ...interface{}) (*sql.Rows, error) {
    51  	rows, err := db.innerDb.Query(query, args...)
    52  	return rows, err
    53  }
    54  
    55  // Close close db
    56  func (db *Storage) Close() (err error) {
    57  	err = db.innerDb.Close()
    58  	return
    59  }
    60  
    61  // NewStorage creates a new storage
    62  func NewStorage(dbType DbType, connection string, tableName string) (*Storage, error) {
    63  
    64  	driver, appendStmt, selectStmt, err := getStatements(dbType, tableName)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	db, err := sql.Open(driver, connection)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	if err = db.Ping(); err != nil {
    75  		db.Close()
    76  		return nil, err
    77  	}
    78  
    79  	storage := &Storage{
    80  		innerDb:                   db,
    81  		DbType:                    dbType,
    82  		AppendStatement:           appendStmt,
    83  		SelectBySourceIDStatement: selectStmt,
    84  	}
    85  	return storage, nil
    86  }
    87  
    88  // NewStorageFinalized creates a new storage with a passed in db argument
    89  func NewStorageFinalized(db *sql.DB, dbType DbType, tableName string) (*Storage, error) {
    90  
    91  	_, appendStmt, selectStmt, err := getStatements(dbType, tableName)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	storage := &Storage{
    97  		innerDb:                   db,
    98  		DbType:                    dbType,
    99  		AppendStatement:           appendStmt,
   100  		SelectBySourceIDStatement: selectStmt,
   101  	}
   102  	return storage, nil
   103  }
   104  
   105  func getStatements(dbType DbType, tableName string) (string, string, string, error) {
   106  
   107  	switch dbType {
   108  
   109  	case MSSQL:
   110  		return "mssql", fmt.Sprintf("INSERT INTO %s (SourceId, Created, EventType, Version, Payload) VALUES (?, ?, ?, ?, ?)", tableName),
   111  			fmt.Sprintf("SELECT Id, CAST(SourceId AS CHAR(36)), Created, EventType, Version, Payload FROM %s WHERE SourceId = ?", tableName), nil
   112  
   113  	case PostgreSQL:
   114  		return "postgres", fmt.Sprintf(`INSERT INTO %s ("SourceId", "Created", "EventType", "Version", "Payload") VALUES ($1, $2, $3, $4, $5)`, tableName),
   115  			fmt.Sprintf(`SELECT "Id", "SourceId", "Created", "EventType", "Version", "Payload" FROM %s WHERE "SourceId" = $1`, tableName), nil
   116  
   117  	default:
   118  		return "", "", "", fmt.Errorf("DB type %d is not supported", dbType)
   119  	}
   120  }