diff --git a/README.md b/README.md index 25d0791..618e686 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # GʀᴇᴀᴛAᴘᴇ +![image](https://img.shields.io/badge/Go-00A7D0?style=for-the-badge&logo=go&logoColor=white) ![image](https://img.shields.io/badge/ActivityPub-DD307D?style=for-the-badge&logoColor=white) ![image](https://img.shields.io/badge/JSON--LD-FF6600?style=for-the-badge&logo=json&logoColor=white) ![image](https://img.shields.io/badge/Sqlite-449A45?style=for-the-badge&logo=sqlite&logoColor=white) ![image](https://img.shields.io/badge/MySQL-32738C?style=for-the-badge&logo=mysql&logoColor=white) + **greatape** is a free **social audio & video** social-media platform that can be used via an app. **greatape** is a Fediverse technology that supports Federation via ActivityPub. diff --git a/greataped/app/models/repos/auth.go b/greataped/app/models/repos/auth.go index d680f0a..11e0d30 100644 --- a/greataped/app/models/repos/auth.go +++ b/greataped/app/models/repos/auth.go @@ -24,12 +24,12 @@ type User struct { // CreateUser create a user entry in the user's table func CreateUser(user *User) *gorm.DB { - return db.DB.Create(user) + return db.Executor.Create(user) } // FindUser searches the user's table with the condition given func FindUser(dest interface{}, conds ...interface{}) *gorm.DB { - return db.DB.Model(&User{}).Take(dest, conds...) + return db.Executor.Model(&User{}).Take(dest, conds...) } // FindUserById searches the user's table with the id given @@ -49,5 +49,5 @@ func FindUserByUsername(dest interface{}, name string) *gorm.DB { // UpdateProfile updates the user's profile with the info given func UpdateProfile(userId interface{}, data interface{}) *gorm.DB { - return db.DB.Model(&User{}).Where("id = ?", userId).Updates(data) + return db.Executor.Model(&User{}).Where("id = ?", userId).Updates(data) } diff --git a/greataped/app/models/repos/followers.go b/greataped/app/models/repos/followers.go index 4c1b266..d12792b 100644 --- a/greataped/app/models/repos/followers.go +++ b/greataped/app/models/repos/followers.go @@ -16,15 +16,15 @@ type Follower struct { // CreateFollower creates a new entry in the followers's table func CreateFollower(follower *Follower) *gorm.DB { - return db.DB.Create(follower) + return db.Executor.Create(follower) } // FindFollowers finds the user's followers func FindFollowers(dest interface{}, userIden interface{}) *gorm.DB { - return db.DB.Model(&Follower{}).Find(dest, "`target` = ?", userIden) + return db.Executor.Model(&Follower{}).Find(dest, "`target` = ?", userIden) } // AcceptFollower accepts a follow request func AcceptFollower(id interface{}) *gorm.DB { - return db.DB.Model(&Follower{}).Where("id = ?", id).Update("accepted", true) + return db.Executor.Model(&Follower{}).Where("id = ?", id).Update("accepted", true) } diff --git a/greataped/app/models/repos/following.go b/greataped/app/models/repos/following.go index 4025bf6..11bcfdf 100644 --- a/greataped/app/models/repos/following.go +++ b/greataped/app/models/repos/following.go @@ -15,10 +15,10 @@ type Following struct { // CreateFollowing creates a new entry in the following's table func CreateFollowing(following *Following) *gorm.DB { - return db.DB.Create(following) + return db.Executor.Create(following) } // FindFollowing finds what accounts the user is following func FindFollowing(dest interface{}, userIden interface{}) *gorm.DB { - return db.DB.Model(&Follower{}).Find(dest, "`handle` = ?", userIden) + return db.Executor.Model(&Follower{}).Find(dest, "`handle` = ?", userIden) } diff --git a/greataped/app/models/repos/inbox.go b/greataped/app/models/repos/inbox.go index 98049de..87f0eb3 100644 --- a/greataped/app/models/repos/inbox.go +++ b/greataped/app/models/repos/inbox.go @@ -18,18 +18,18 @@ type IncomingActivity struct { // CreateIncomingActivity creates an activity entry in the incoming activities table func CreateIncomingActivity(activity *IncomingActivity) *gorm.DB { - return db.DB.Create(activity) + return db.Executor.Create(activity) } // FindIncomingActivitiesForUser finds the activities posted to user func FindIncomingActivitiesForUser(dest interface{}, userIden interface{}) *gorm.DB { - return db.DB.Model(&IncomingActivity{}).Find(dest, "`to` = ?", userIden) + return db.Executor.Model(&IncomingActivity{}).Find(dest, "`to` = ?", userIden) } // FindIncomingActivity searches the incoming activities table with the condition given // and returns a single record. func FindIncomingActivity(dest interface{}, conds ...interface{}) *gorm.DB { - return db.DB.Model(&IncomingActivity{}).Take(dest, conds...) + return db.Executor.Model(&IncomingActivity{}).Take(dest, conds...) } // FindIncomingActivityById searches the incoming activities table with the id given diff --git a/greataped/app/models/repos/outbox.go b/greataped/app/models/repos/outbox.go index 041cbc3..dddb207 100644 --- a/greataped/app/models/repos/outbox.go +++ b/greataped/app/models/repos/outbox.go @@ -18,18 +18,18 @@ type OutgoingActivity struct { // CreateOutgoingActivity creates an activity entry in the outgoing activities table func CreateOutgoingActivity(activity *OutgoingActivity) *gorm.DB { - return db.DB.Create(activity) + return db.Executor.Create(activity) } // FindOutgoingActivitiesByUser finds the activities posted by user func FindOutgoingActivitiesByUser(dest interface{}, userIden interface{}) *gorm.DB { - return db.DB.Model(&OutgoingActivity{}).Find(dest, "`from` = ?", userIden) + return db.Executor.Model(&OutgoingActivity{}).Find(dest, "`from` = ?", userIden) } // FindOutgoingActivity searches the outgoing activities table with the condition given // and returns a single record. func FindOutgoingActivity(dest interface{}, conds ...interface{}) *gorm.DB { - return db.DB.Model(&OutgoingActivity{}).Take(dest, conds...) + return db.Executor.Model(&OutgoingActivity{}).Take(dest, conds...) } // FindOutgoingActivityById searches the outgoing activities table with the id given diff --git a/greataped/db/factory.go b/greataped/db/factory.go index 7bccd3c..61f5309 100644 --- a/greataped/db/factory.go +++ b/greataped/db/factory.go @@ -1,15 +1,24 @@ package db -import "contracts" +import ( + . "contracts" -const ( - SqliteStorage contracts.StorageType = 0 + "gorm.io/gorm" ) -func CreateStorage(componentType contracts.StorageType) contracts.IStorage { +var Executor *gorm.DB + +const ( + SqliteStorage StorageType = 0 + MySQLStorage StorageType = 1 +) + +func CreateStorage(componentType StorageType) IStorage { switch componentType { case SqliteStorage: return NewSqliteStorage() + case MySQLStorage: + return NewMySQLStorage() default: panic("unknown_storage_type") } diff --git a/greataped/db/go.mod b/greataped/db/go.mod index f2f2aad..85b5ee9 100644 --- a/greataped/db/go.mod +++ b/greataped/db/go.mod @@ -4,11 +4,13 @@ go 1.19 require ( github.com/mattn/go-sqlite3 v1.14.14 + gorm.io/driver/mysql v1.3.6 gorm.io/driver/sqlite v1.3.6 gorm.io/gorm v1.23.8 ) require ( + github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect ) diff --git a/greataped/db/go.sum b/greataped/db/go.sum index b8b1773..86387da 100644 --- a/greataped/db/go.sum +++ b/greataped/db/go.sum @@ -1,3 +1,5 @@ +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -6,6 +8,8 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM= +gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE= gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= diff --git a/greataped/db/mysql.go b/greataped/db/mysql.go new file mode 100644 index 0000000..4f507cf --- /dev/null +++ b/greataped/db/mysql.go @@ -0,0 +1,51 @@ +package db + +import ( + "contracts" + "log" + "time" + + _ "github.com/mattn/go-sqlite3" + "gorm.io/driver/mysql" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +type mysqlStorage struct { + // Underlying database connection + database *gorm.DB + dsn string +} + +func NewMySQLStorage() contracts.IStorage { + return &mysqlStorage{} +} + +// Connect initiate the database connection and migrate all the tables +func (storage *mysqlStorage) Connect(dsn string) { + storage.dsn = dsn + + database, err := gorm.Open(mysql.Open(storage.dsn), &gorm.Config{ + NowFunc: func() time.Time { return time.Now().Local() }, + Logger: logger.Default.LogMode(logger.Info), + }) + + if err != nil { + log.Println("[DATABASE]::CONNECTION_ERROR") + panic(err) + } + + storage.database = database + Executor = storage.database + + log.Println("[DATABASE]::CONNECTED") +} + +// Migrate migrates all the database tables +func (storage *mysqlStorage) Migrate(tables ...interface{}) error { + return storage.database.AutoMigrate(tables...) +} + +func (storage *mysqlStorage) Prepare(string) contracts.IQuery { + return nil +} diff --git a/greataped/db/sqlite.go b/greataped/db/sqlite.go index 8877b5d..83f266b 100644 --- a/greataped/db/sqlite.go +++ b/greataped/db/sqlite.go @@ -11,8 +11,6 @@ import ( "gorm.io/gorm/logger" ) -var DB *gorm.DB - type sqliteStorage struct { // Underlying database connection database *gorm.DB @@ -38,7 +36,7 @@ func (storage *sqliteStorage) Connect(path string) { } storage.database = database - DB = storage.database + Executor = storage.database log.Println("[DATABASE]::CONNECTED") }