Last active
January 15, 2016 12:44
-
-
Save josephspurrier/7742f8e863ee46dd12ba to your computer and use it in GitHub Desktop.
MongoDB in GoWebApp: https://github.com/josephspurrier/gowebapp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"Database": { | |
... | |
"MongoDB": { | |
"URL": "127.0.0.1", | |
"Database": "gowebapp" | |
} | |
}, | |
... | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package database | |
import ( | |
"fmt" | |
"log" | |
"time" | |
_ "github.com/go-sql-driver/mysql" | |
"github.com/jmoiron/sqlx" | |
_ "github.com/mattn/go-sqlite3" | |
"gopkg.in/mgo.v2" | |
) | |
var ( | |
Sql *sqlx.DB // SQL wrapper | |
Mongo *mgo.Session // Mongo wrapper | |
databases DatabaseInfo // Database info | |
) | |
type DatabaseType string | |
const ( | |
TypeMySQL DatabaseType = "MySQL" | |
TypeSQLite DatabaseType = "SQLite" | |
TypeMongoDB DatabaseType = "MongoDB" | |
) | |
type DatabaseInfo struct { | |
Type DatabaseType | |
MySQL MySQLInfo | |
SQLite SQLiteInfo | |
MongoDB MongoDBInfo | |
} | |
// MySQLInfo is the details for the database connection | |
type MySQLInfo struct { | |
Username string | |
Password string | |
Name string | |
Hostname string | |
Port int | |
Parameter string | |
} | |
// SQLiteInfo is the details for the database connection | |
type SQLiteInfo struct { | |
Parameter string | |
} | |
// MongoDBInfo is the details for the database connection | |
type MongoDBInfo struct { | |
URL string | |
Database string | |
} | |
// DSN returns the Data Source Name | |
func DSN(ci MySQLInfo) string { | |
// Example: root:@tcp(localhost:3306)/test | |
return ci.Username + | |
":" + | |
ci.Password + | |
"@tcp(" + | |
ci.Hostname + | |
":" + | |
fmt.Sprintf("%d", ci.Port) + | |
")/" + | |
ci.Name + ci.Parameter | |
} | |
// Connect to the database | |
func Connect(d DatabaseInfo) { | |
var err error | |
// Store the config | |
databases = d | |
switch d.Type { | |
case TypeMySQL: | |
// Connect to MySQL | |
if Sql, err = sqlx.Connect("mysql", DSN(d.MySQL)); err != nil { | |
log.Println("MySQL Driver Error", err) | |
} | |
// Check if is alive | |
if err = Sql.Ping(); err != nil { | |
log.Println("Database Error", err) | |
} | |
case TypeSQLite: | |
// Connect to SQLite | |
if Sql, err = sqlx.Connect("sqlite3", d.SQLite.Parameter); err != nil { | |
log.Println("SQLite Driver Error", err) | |
} | |
// Check if is alive | |
if err = Sql.Ping(); err != nil { | |
log.Println("Database Error", err) | |
} | |
case TypeMongoDB: | |
// Connect to MongoDB | |
if Mongo, err = mgo.DialWithTimeout(d.MongoDB.URL, 5); err != nil { | |
log.Println("MongoDB Driver Error", err) | |
return | |
} | |
// Prevents these errors: read tcp 127.0.0.1:27017: i/o timeout | |
Mongo.SetSocketTimeout(1 * time.Second) | |
// Check if is alive | |
if err = Mongo.Ping(); err != nil { | |
log.Println("Database Error", err) | |
} | |
default: | |
log.Println("No registered database in config") | |
} | |
} | |
// CheckConnection returns true if MongoDB is available | |
func CheckConnection() bool { | |
if Mongo == nil { | |
Connect(databases) | |
} | |
if Mongo != nil { | |
return true | |
} | |
return false | |
} | |
// ReadConfig returns the database information | |
func ReadConfig() DatabaseInfo { | |
return databases | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package model | |
import ( | |
"database/sql" | |
"errors" | |
"fmt" | |
"time" | |
"github.com/josephspurrier/gowebapp/shared/database" | |
"gopkg.in/mgo.v2" | |
"gopkg.in/mgo.v2/bson" | |
) | |
// ***************************************************************************** | |
// User | |
// ***************************************************************************** | |
// User table contains the information for each user | |
type User struct { | |
objectId bson.ObjectId `bson:"_id"` | |
id uint32 `db:"id" bson:"id,omitempty"` | |
First_name string `db:"first_name" bson:"first_name"` | |
Last_name string `db:"last_name" bson:"last_name"` | |
Email string `db:"email" bson:"email"` | |
Password string `db:"password" bson:"password"` | |
Status_id uint8 `db:"status_id" bson:"status_id"` | |
Created_at time.Time `db:"created_at" bson:"created_at"` | |
Updated_at time.Time `db:"updated_at" bson:"updated_at"` | |
Deleted uint8 `db:"deleted" bson:"deleted"` | |
} | |
func (u *User) Id() string { | |
r := "" | |
switch database.ReadConfig().Type { | |
case database.TypeMySQL, database.TypeSQLite: | |
r = fmt.Sprintf("%v", u.id) | |
case database.TypeMongoDB: | |
r = u.objectId.Hex() | |
} | |
return r | |
} | |
// User_status table contains every possible user status (active/inactive) | |
type User_status struct { | |
Id uint8 `db:"id" bson:"id"` | |
Status string `db:"status" bson:"status"` | |
Created_at time.Time `db:"created_at" bson:"created_at"` | |
Updated_at time.Time `db:"updated_at" bson:"updated_at"` | |
Deleted uint8 `db:"deleted" bson:"deleted"` | |
} | |
var ( | |
ErrCode = errors.New("Case statement in code is not correct.") | |
ErrNoResult = errors.New("Result not found.") | |
ErrUnavailable = errors.New("Database is unavailable.") | |
) | |
func standardizeError(err error) error { | |
if err == sql.ErrNoRows || err == mgo.ErrNotFound { | |
return ErrNoResult | |
} | |
return err | |
} | |
// UserByEmail gets user information from email | |
func UserByEmail(email string) (User, error) { | |
var err error | |
result := User{} | |
switch database.ReadConfig().Type { | |
case database.TypeMySQL, database.TypeSQLite: | |
err = database.Sql.Get(&result, "SELECT id, password, status_id, first_name FROM user WHERE email = ? LIMIT 1", email) | |
case database.TypeMongoDB: | |
if database.CheckConnection() { | |
session := database.Mongo.Copy() | |
defer session.Close() | |
c := session.DB(database.ReadConfig().MongoDB.Database).C("user") | |
err = c.Find(bson.M{"email": email}).One(&result) | |
} else { | |
err = ErrUnavailable | |
} | |
default: | |
err = ErrCode | |
} | |
return result, standardizeError(err) | |
} | |
// UserCreate creates user | |
func UserCreate(first_name, last_name, email, password string) error { | |
var err error | |
switch database.ReadConfig().Type { | |
case database.TypeMySQL, database.TypeSQLite: | |
_, err = database.Sql.Exec("INSERT INTO user (first_name, last_name, email, password) VALUES (?,?,?,?)", first_name, | |
last_name, email, password) | |
case database.TypeMongoDB: | |
if database.CheckConnection() { | |
session := database.Mongo.Copy() | |
defer session.Close() | |
c := session.DB(database.ReadConfig().MongoDB.Database).C("user") | |
err = c.Insert(&User{objectId: bson.NewObjectId(), First_name: first_name, Last_name: last_name, Email: email, | |
Password: password, Status_id: 1, Created_at: time.Now(), Updated_at: time.Now()}) | |
} else { | |
err = ErrUnavailable | |
} | |
default: | |
err = ErrCode | |
} | |
return standardizeError(err) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
These code changes allow you to use MongoDB with GoWebApp: https://github.com/josephspurrier/gowebapp