Renamed a few querygen structs.

Moved the accumulator sub-builders into their own file.
Implemented OO methods for the prebuilders.

Began converting the generated queries over to the OO methods.
This commit is contained in:
Azareal 2017-11-12 05:25:04 +00:00
parent 2545d4adde
commit 2047fed0b9
17 changed files with 741 additions and 548 deletions

View File

@ -295,8 +295,8 @@ func PermmapToQuery(permmap map[string]ForumPerms, fid int) error {
} }
addForumPermsToForumAdminsTx, err := qgen.Builder.SimpleInsertSelectTx(tx, addForumPermsToForumAdminsTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""}, qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""}, qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""},
) )
if err != nil { if err != nil {
return err return err
@ -313,8 +313,8 @@ func PermmapToQuery(permmap map[string]ForumPerms, fid int) error {
} }
addForumPermsToForumStaffTx, err := qgen.Builder.SimpleInsertSelectTx(tx, addForumPermsToForumStaffTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""}, qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 1", "", ""}, qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 1", "", ""},
) )
if err != nil { if err != nil {
return err return err
@ -330,8 +330,8 @@ func PermmapToQuery(permmap map[string]ForumPerms, fid int) error {
} }
addForumPermsToForumMembersTx, err := qgen.Builder.SimpleInsertSelectTx(tx, addForumPermsToForumMembersTx, err := qgen.Builder.SimpleInsertSelectTx(tx,
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""}, qgen.DBInsert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 0 AND is_banned = 0", "", ""}, qgen.DBSelect{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 0 AND is_mod = 0 AND is_banned = 0", "", ""},
) )
if err != nil { if err != nil {
return err return err

View File

@ -4,12 +4,14 @@
/* Super experimental and incomplete. DON'T USE IT YET! */ /* Super experimental and incomplete. DON'T USE IT YET! */
package main package main
import "strings" import (
"database/sql"
"strings"
//import "time" "./common"
import "database/sql" "./query_gen/lib"
import _ "github.com/lib/pq" _ "github.com/lib/pq"
import "./query_gen/lib" )
// TODO: Add support for SSL for all database drivers, not just pgsql // TODO: Add support for SSL for all database drivers, not just pgsql
var db_sslmode = "disable" // verify-full var db_sslmode = "disable" // verify-full
@ -23,10 +25,10 @@ func initPgsql() (err error) {
// TODO: Investigate connect_timeout to see what it does exactly and whether it's relevant to us // TODO: Investigate connect_timeout to see what it does exactly and whether it's relevant to us
var _dbpassword string var _dbpassword string
if dbpassword != "" { if dbpassword != "" {
_dbpassword = " password='" + _escape_bit(db_config.Password) + "'" _dbpassword = " password='" + _escape_bit(common.DbConfig.Password) + "'"
} }
// TODO: Move this bit to the query gen lib // TODO: Move this bit to the query gen lib
db, err = sql.Open("postgres", "host='"+_escape_bit(db_config.Host)+"' port='"+_escape_bit(db_config.Port)+"' user='"+_escape_bit(db_config.Username)+"' dbname='"+_escape_bit(config.Dbname)+"'"+_dbpassword+" sslmode='"+db_sslmode+"'") db, err = sql.Open("postgres", "host='"+_escape_bit(common.DbConfig.Host)+"' port='"+_escape_bit(common.DbConfig.Port)+"' user='"+_escape_bit(common.DbConfig.Username)+"' dbname='"+_escape_bit(common.Config.Dbname)+"'"+_dbpassword+" sslmode='"+db_sslmode+"'")
if err != nil { if err != nil {
return err return err
} }

View File

@ -82,23 +82,23 @@ func deactivateGuilds() {
// TODO: Stop accessing the query builder directly and add a feature in Gosora which is more easily reversed, if an error comes up during the installation process // TODO: Stop accessing the query builder directly and add a feature in Gosora which is more easily reversed, if an error comes up during the installation process
func installGuilds() error { func installGuilds() error {
guildTableStmt, err := qgen.Builder.CreateTable("guilds", "utf8mb4", "utf8mb4_general_ci", guildTableStmt, err := qgen.Builder.CreateTable("guilds", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"guildID", "int", 0, false, true, ""}, qgen.DBTableColumn{"guildID", "int", 0, false, true, ""},
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"name", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"desc", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"desc", "varchar", 200, false, false, ""},
qgen.DB_Table_Column{"active", "boolean", 1, false, false, ""}, qgen.DBTableColumn{"active", "boolean", 1, false, false, ""},
qgen.DB_Table_Column{"privacy", "smallint", 0, false, false, ""}, qgen.DBTableColumn{"privacy", "smallint", 0, false, false, ""},
qgen.DB_Table_Column{"joinable", "smallint", 0, false, false, "0"}, qgen.DBTableColumn{"joinable", "smallint", 0, false, false, "0"},
qgen.DB_Table_Column{"owner", "int", 0, false, false, ""}, qgen.DBTableColumn{"owner", "int", 0, false, false, ""},
qgen.DB_Table_Column{"memberCount", "int", 0, false, false, ""}, qgen.DBTableColumn{"memberCount", "int", 0, false, false, ""},
qgen.DB_Table_Column{"mainForum", "int", 0, false, false, "0"}, // The board the user lands on when they click on a group, we'll make it possible for group admins to change what users land on qgen.DBTableColumn{"mainForum", "int", 0, false, false, "0"}, // The board the user lands on when they click on a group, we'll make it possible for group admins to change what users land on
//qgen.DB_Table_Column{"boards","varchar",255,false,false,""}, // Cap the max number of boards at 8 to avoid overflowing the confines of a 64-bit integer? //qgen.DBTableColumn{"boards","varchar",255,false,false,""}, // Cap the max number of boards at 8 to avoid overflowing the confines of a 64-bit integer?
qgen.DB_Table_Column{"backdrop", "varchar", 200, false, false, ""}, // File extension for the uploaded file, or an external link qgen.DBTableColumn{"backdrop", "varchar", 200, false, false, ""}, // File extension for the uploaded file, or an external link
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""},
qgen.DB_Table_Column{"lastUpdateTime", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"lastUpdateTime", "datetime", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"guildID", "primary"}, qgen.DBTableKey{"guildID", "primary"},
}, },
) )
if err != nil { if err != nil {
@ -111,14 +111,14 @@ func installGuilds() error {
} }
guildMembersTableStmt, err := qgen.Builder.CreateTable("guilds_members", "", "", guildMembersTableStmt, err := qgen.Builder.CreateTable("guilds_members", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"guildID", "int", 0, false, false, ""}, qgen.DBTableColumn{"guildID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""}, qgen.DBTableColumn{"uid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"rank", "int", 0, false, false, "0"}, /* 0: Member. 1: Mod. 2: Admin. */ qgen.DBTableColumn{"rank", "int", 0, false, false, "0"}, /* 0: Member. 1: Mod. 2: Admin. */
qgen.DB_Table_Column{"posts", "int", 0, false, false, "0"}, /* Per-Group post count. Should we do some sort of score system? */ qgen.DBTableColumn{"posts", "int", 0, false, false, "0"}, /* Per-Group post count. Should we do some sort of score system? */
qgen.DB_Table_Column{"joinedAt", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"joinedAt", "datetime", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
if err != nil { if err != nil {
return err return err

View File

@ -0,0 +1,127 @@
package qgen
import "database/sql"
type accDeleteBuilder struct {
table string
where string
build *Accumulator
}
func (delete *accDeleteBuilder) Where(where string) *accDeleteBuilder {
delete.where = where
return delete
}
func (delete *accDeleteBuilder) Prepare() *sql.Stmt {
return delete.build.SimpleDelete(delete.table, delete.where)
}
type accUpdateBuilder struct {
table string
set string
where string
build *Accumulator
}
func (update *accUpdateBuilder) Set(set string) *accUpdateBuilder {
update.set = set
return update
}
func (update *accUpdateBuilder) Where(where string) *accUpdateBuilder {
update.where = where
return update
}
func (update *accUpdateBuilder) Prepare() *sql.Stmt {
return update.build.SimpleUpdate(update.table, update.set, update.where)
}
type accSelectBuilder struct {
table string
columns string
where string
orderby string
limit string
build *Accumulator
}
func (selectItem *accSelectBuilder) Columns(columns string) *accSelectBuilder {
selectItem.columns = columns
return selectItem
}
func (selectItem *accSelectBuilder) Where(where string) *accSelectBuilder {
selectItem.where = where
return selectItem
}
func (selectItem *accSelectBuilder) Orderby(orderby string) *accSelectBuilder {
selectItem.orderby = orderby
return selectItem
}
func (selectItem *accSelectBuilder) Limit(limit string) *accSelectBuilder {
selectItem.limit = limit
return selectItem
}
func (selectItem *accSelectBuilder) Prepare() *sql.Stmt {
return selectItem.build.SimpleSelect(selectItem.table, selectItem.columns, selectItem.where, selectItem.orderby, selectItem.limit)
}
func (selectItem *accSelectBuilder) Query(args ...interface{}) (*sql.Rows, error) {
stmt := selectItem.Prepare()
if stmt != nil {
return stmt.Query(args...)
}
return nil, selectItem.build.FirstError()
}
type accInsertBuilder struct {
table string
columns string
fields string
build *Accumulator
}
func (insert *accInsertBuilder) Columns(columns string) *accInsertBuilder {
insert.columns = columns
return insert
}
func (insert *accInsertBuilder) Fields(fields string) *accInsertBuilder {
insert.fields = fields
return insert
}
func (insert *accInsertBuilder) Prepare() *sql.Stmt {
return insert.build.SimpleInsert(insert.table, insert.columns, insert.fields)
}
type accCountBuilder struct {
table string
where string
limit string
build *Accumulator
}
func (count *accCountBuilder) Where(where string) *accCountBuilder {
count.where = where
return count
}
func (count *accCountBuilder) Limit(limit string) *accCountBuilder {
count.limit = limit
return count
}
func (count *accCountBuilder) Prepare() *sql.Stmt {
return count.build.SimpleCount(count.table, count.where, count.limit)
}

View File

@ -7,7 +7,7 @@ import (
type Accumulator struct { type Accumulator struct {
conn *sql.DB conn *sql.DB
adapter DB_Adapter adapter Adapter
firstErr error firstErr error
} }
@ -24,7 +24,7 @@ func (build *Accumulator) SetAdapter(name string) error {
return nil return nil
} }
func (build *Accumulator) GetAdapter() DB_Adapter { func (build *Accumulator) GetAdapter() Adapter {
return build.adapter return build.adapter
} }
@ -82,7 +82,7 @@ func (build *Accumulator) SimpleInnerJoin(table1 string, table2 string, columns
return build.prepare(build.adapter.SimpleInnerJoin("_builder", table1, table2, columns, joiners, where, orderby, limit)) return build.prepare(build.adapter.SimpleInnerJoin("_builder", table1, table2, columns, joiners, where, orderby, limit))
} }
func (build *Accumulator) CreateTable(table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) *sql.Stmt { func (build *Accumulator) CreateTable(table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) *sql.Stmt {
return build.prepare(build.adapter.CreateTable("_builder", table, charset, collation, columns, keys)) return build.prepare(build.adapter.CreateTable("_builder", table, charset, collation, columns, keys))
} }
@ -90,15 +90,15 @@ func (build *Accumulator) SimpleInsert(table string, columns string, fields stri
return build.prepare(build.adapter.SimpleInsert("_builder", table, columns, fields)) return build.prepare(build.adapter.SimpleInsert("_builder", table, columns, fields))
} }
func (build *Accumulator) SimpleInsertSelect(ins DB_Insert, sel DB_Select) *sql.Stmt { func (build *Accumulator) SimpleInsertSelect(ins DBInsert, sel DBSelect) *sql.Stmt {
return build.prepare(build.adapter.SimpleInsertSelect("_builder", ins, sel)) return build.prepare(build.adapter.SimpleInsertSelect("_builder", ins, sel))
} }
func (build *Accumulator) SimpleInsertLeftJoin(ins DB_Insert, sel DB_Join) *sql.Stmt { func (build *Accumulator) SimpleInsertLeftJoin(ins DBInsert, sel DBJoin) *sql.Stmt {
return build.prepare(build.adapter.SimpleInsertLeftJoin("_builder", ins, sel)) return build.prepare(build.adapter.SimpleInsertLeftJoin("_builder", ins, sel))
} }
func (build *Accumulator) SimpleInsertInnerJoin(ins DB_Insert, sel DB_Join) *sql.Stmt { func (build *Accumulator) SimpleInsertInnerJoin(ins DBInsert, sel DBJoin) *sql.Stmt {
return build.prepare(build.adapter.SimpleInsertInnerJoin("_builder", ins, sel)) return build.prepare(build.adapter.SimpleInsertInnerJoin("_builder", ins, sel))
} }
@ -146,7 +146,7 @@ func (build *Accumulator) SimpleInnerJoinTx(tx *sql.Tx, table1 string, table2 st
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
func (build *Accumulator) CreateTableTx(tx *sql.Tx, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (stmt *sql.Stmt) { func (build *Accumulator) CreateTableTx(tx *sql.Tx, table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (stmt *sql.Stmt) {
res, err := build.adapter.CreateTable("_builder", table, charset, collation, columns, keys) res, err := build.adapter.CreateTable("_builder", table, charset, collation, columns, keys)
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
@ -156,17 +156,17 @@ func (build *Accumulator) SimpleInsertTx(tx *sql.Tx, table string, columns strin
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
func (build *Accumulator) SimpleInsertSelectTx(tx *sql.Tx, ins DB_Insert, sel DB_Select) (stmt *sql.Stmt) { func (build *Accumulator) SimpleInsertSelectTx(tx *sql.Tx, ins DBInsert, sel DBSelect) (stmt *sql.Stmt) {
res, err := build.adapter.SimpleInsertSelect("_builder", ins, sel) res, err := build.adapter.SimpleInsertSelect("_builder", ins, sel)
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
func (build *Accumulator) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt) { func (build *Accumulator) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DBInsert, sel DBJoin) (stmt *sql.Stmt) {
res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel) res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel)
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
func (build *Accumulator) SimpleInsertInnerJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt) { func (build *Accumulator) SimpleInsertInnerJoinTx(tx *sql.Tx, ins DBInsert, sel DBJoin) (stmt *sql.Stmt) {
res, err := build.adapter.SimpleInsertInnerJoin("_builder", ins, sel) res, err := build.adapter.SimpleInsertInnerJoin("_builder", ins, sel)
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
@ -187,146 +187,22 @@ func (build *Accumulator) PurgeTx(tx *sql.Tx, table string) (stmt *sql.Stmt) {
return build.prepareTx(tx, res, err) return build.prepareTx(tx, res, err)
} }
func (build *Accumulator) Delete(table string) *deleteBuilder { func (build *Accumulator) Delete(table string) *accDeleteBuilder {
return &deleteBuilder{table, "", build} return &accDeleteBuilder{table, "", build}
} }
type deleteBuilder struct { func (build *Accumulator) Update(table string) *accUpdateBuilder {
table string return &accUpdateBuilder{table, "", "", build}
where string
build *Accumulator
} }
func (delete *deleteBuilder) Where(where string) *deleteBuilder { func (build *Accumulator) Select(table string) *accSelectBuilder {
delete.where = where return &accSelectBuilder{table, "", "", "", "", build}
return delete
} }
func (delete *deleteBuilder) Prepare() *sql.Stmt { func (build *Accumulator) Insert(table string) *accInsertBuilder {
return delete.build.SimpleDelete(delete.table, delete.where) return &accInsertBuilder{table, "", "", build}
} }
func (build *Accumulator) Update(table string) *updateBuilder { func (build *Accumulator) Count(table string) *accCountBuilder {
return &updateBuilder{table, "", "", build} return &accCountBuilder{table, "", "", build}
}
type updateBuilder struct {
table string
set string
where string
build *Accumulator
}
func (update *updateBuilder) Set(set string) *updateBuilder {
update.set = set
return update
}
func (update *updateBuilder) Where(where string) *updateBuilder {
update.where = where
return update
}
func (update *updateBuilder) Prepare() *sql.Stmt {
return update.build.SimpleUpdate(update.table, update.set, update.where)
}
func (build *Accumulator) Select(table string) *selectBuilder {
return &selectBuilder{table, "", "", "", "", build}
}
type selectBuilder struct {
table string
columns string
where string
orderby string
limit string
build *Accumulator
}
func (selectItem *selectBuilder) Columns(columns string) *selectBuilder {
selectItem.columns = columns
return selectItem
}
func (selectItem *selectBuilder) Where(where string) *selectBuilder {
selectItem.where = where
return selectItem
}
func (selectItem *selectBuilder) Orderby(orderby string) *selectBuilder {
selectItem.orderby = orderby
return selectItem
}
func (selectItem *selectBuilder) Limit(limit string) *selectBuilder {
selectItem.limit = limit
return selectItem
}
func (selectItem *selectBuilder) Prepare() *sql.Stmt {
return selectItem.build.SimpleSelect(selectItem.table, selectItem.columns, selectItem.where, selectItem.orderby, selectItem.limit)
}
func (selectItem *selectBuilder) Query(args ...interface{}) (*sql.Rows, error) {
stmt := selectItem.Prepare()
if stmt != nil {
return stmt.Query(args...)
}
return nil, selectItem.build.FirstError()
}
func (build *Accumulator) Insert(table string) *insertBuilder {
return &insertBuilder{table, "", "", build}
}
type insertBuilder struct {
table string
columns string
fields string
build *Accumulator
}
func (insert *insertBuilder) Columns(columns string) *insertBuilder {
insert.columns = columns
return insert
}
func (insert *insertBuilder) Fields(fields string) *insertBuilder {
insert.fields = fields
return insert
}
func (insert *insertBuilder) Prepare() *sql.Stmt {
return insert.build.SimpleInsert(insert.table, insert.columns, insert.fields)
}
func (build *Accumulator) Count(table string) *countBuilder {
return &countBuilder{table, "", "", build}
}
type countBuilder struct {
table string
where string
limit string
build *Accumulator
}
func (count *countBuilder) Where(where string) *countBuilder {
count.where = where
return count
}
func (count *countBuilder) Limit(limit string) *countBuilder {
count.limit = limit
return count
}
func (count *countBuilder) Prepare() *sql.Stmt {
return count.build.SimpleCount(count.table, count.where, count.limit)
} }

View File

@ -13,7 +13,7 @@ func init() {
// A set of wrappers around the generator methods, so that we can use this inline in Gosora // A set of wrappers around the generator methods, so that we can use this inline in Gosora
type builder struct { type builder struct {
conn *sql.DB conn *sql.DB
adapter DB_Adapter adapter Adapter
} }
func (build *builder) Accumulator() *Accumulator { func (build *builder) Accumulator() *Accumulator {
@ -33,7 +33,7 @@ func (build *builder) SetAdapter(name string) error {
return nil return nil
} }
func (build *builder) GetAdapter() DB_Adapter { func (build *builder) GetAdapter() Adapter {
return build.adapter return build.adapter
} }
@ -77,7 +77,7 @@ func (build *builder) SimpleInnerJoin(table1 string, table2 string, columns stri
return build.prepare(build.adapter.SimpleInnerJoin("_builder", table1, table2, columns, joiners, where, orderby, limit)) return build.prepare(build.adapter.SimpleInnerJoin("_builder", table1, table2, columns, joiners, where, orderby, limit))
} }
func (build *builder) CreateTable(table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (stmt *sql.Stmt, err error) { func (build *builder) CreateTable(table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (stmt *sql.Stmt, err error) {
return build.prepare(build.adapter.CreateTable("_builder", table, charset, collation, columns, keys)) return build.prepare(build.adapter.CreateTable("_builder", table, charset, collation, columns, keys))
} }
@ -85,15 +85,15 @@ func (build *builder) SimpleInsert(table string, columns string, fields string)
return build.prepare(build.adapter.SimpleInsert("_builder", table, columns, fields)) return build.prepare(build.adapter.SimpleInsert("_builder", table, columns, fields))
} }
func (build *builder) SimpleInsertSelect(ins DB_Insert, sel DB_Select) (stmt *sql.Stmt, err error) { func (build *builder) SimpleInsertSelect(ins DBInsert, sel DBSelect) (stmt *sql.Stmt, err error) {
return build.prepare(build.adapter.SimpleInsertSelect("_builder", ins, sel)) return build.prepare(build.adapter.SimpleInsertSelect("_builder", ins, sel))
} }
func (build *builder) SimpleInsertLeftJoin(ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) { func (build *builder) SimpleInsertLeftJoin(ins DBInsert, sel DBJoin) (stmt *sql.Stmt, err error) {
return build.prepare(build.adapter.SimpleInsertLeftJoin("_builder", ins, sel)) return build.prepare(build.adapter.SimpleInsertLeftJoin("_builder", ins, sel))
} }
func (build *builder) SimpleInsertInnerJoin(ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) { func (build *builder) SimpleInsertInnerJoin(ins DBInsert, sel DBJoin) (stmt *sql.Stmt, err error) {
return build.prepare(build.adapter.SimpleInsertInnerJoin("_builder", ins, sel)) return build.prepare(build.adapter.SimpleInsertInnerJoin("_builder", ins, sel))
} }
@ -143,7 +143,7 @@ func (build *builder) SimpleInnerJoinTx(tx *sql.Tx, table1 string, table2 string
return tx.Prepare(res) return tx.Prepare(res)
} }
func (build *builder) CreateTableTx(tx *sql.Tx, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (stmt *sql.Stmt, err error) { func (build *builder) CreateTableTx(tx *sql.Tx, table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (stmt *sql.Stmt, err error) {
res, err := build.adapter.CreateTable("_builder", table, charset, collation, columns, keys) res, err := build.adapter.CreateTable("_builder", table, charset, collation, columns, keys)
if err != nil { if err != nil {
return stmt, err return stmt, err
@ -159,7 +159,7 @@ func (build *builder) SimpleInsertTx(tx *sql.Tx, table string, columns string, f
return tx.Prepare(res) return tx.Prepare(res)
} }
func (build *builder) SimpleInsertSelectTx(tx *sql.Tx, ins DB_Insert, sel DB_Select) (stmt *sql.Stmt, err error) { func (build *builder) SimpleInsertSelectTx(tx *sql.Tx, ins DBInsert, sel DBSelect) (stmt *sql.Stmt, err error) {
res, err := build.adapter.SimpleInsertSelect("_builder", ins, sel) res, err := build.adapter.SimpleInsertSelect("_builder", ins, sel)
if err != nil { if err != nil {
return stmt, err return stmt, err
@ -167,7 +167,7 @@ func (build *builder) SimpleInsertSelectTx(tx *sql.Tx, ins DB_Insert, sel DB_Sel
return tx.Prepare(res) return tx.Prepare(res)
} }
func (build *builder) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) { func (build *builder) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DBInsert, sel DBJoin) (stmt *sql.Stmt, err error) {
res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel) res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel)
if err != nil { if err != nil {
return stmt, err return stmt, err
@ -175,7 +175,7 @@ func (build *builder) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_J
return tx.Prepare(res) return tx.Prepare(res)
} }
func (build *builder) SimpleInsertInnerJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt, err error) { func (build *builder) SimpleInsertInnerJoinTx(tx *sql.Tx, ins DBInsert, sel DBJoin) (stmt *sql.Stmt, err error) {
res, err := build.adapter.SimpleInsertInnerJoin("_builder", ins, sel) res, err := build.adapter.SimpleInsertInnerJoin("_builder", ins, sel)
if err != nil { if err != nil {
return stmt, err return stmt, err

View File

@ -16,7 +16,7 @@ type DB_Install_Instruction struct {
// A set of wrappers around the generator methods, so we can use this in the installer // A set of wrappers around the generator methods, so we can use this in the installer
// TODO: Re-implement the query generation, query builder and installer adapters as layers on-top of a query text adapter // TODO: Re-implement the query generation, query builder and installer adapters as layers on-top of a query text adapter
type installer struct { type installer struct {
adapter DB_Adapter adapter Adapter
instructions []DB_Install_Instruction instructions []DB_Install_Instruction
plugins []QueryPlugin plugins []QueryPlugin
} }
@ -31,7 +31,7 @@ func (install *installer) SetAdapter(name string) error {
return nil return nil
} }
func (install *installer) SetAdapterInstance(adapter DB_Adapter) { func (install *installer) SetAdapterInstance(adapter Adapter) {
install.adapter = adapter install.adapter = adapter
install.instructions = []DB_Install_Instruction{} install.instructions = []DB_Install_Instruction{}
} }
@ -40,7 +40,7 @@ func (install *installer) RegisterPlugin(plugin QueryPlugin) {
install.plugins = append(install.plugins, plugin) install.plugins = append(install.plugins, plugin)
} }
func (install *installer) CreateTable(table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) error { func (install *installer) CreateTable(table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) error {
for _, plugin := range install.plugins { for _, plugin := range install.plugins {
err := plugin.Hook("CreateTableStart", table, charset, collation, columns, keys) err := plugin.Hook("CreateTableStart", table, charset, collation, columns, keys)
if err != nil { if err != nil {

View File

@ -0,0 +1,174 @@
package qgen
type deletePrebuilder struct {
name string
table string
where string
build Adapter
}
func (delete *deletePrebuilder) Table(table string) *deletePrebuilder {
delete.table = table
return delete
}
func (delete *deletePrebuilder) Where(where string) *deletePrebuilder {
delete.where = where
return delete
}
func (delete *deletePrebuilder) Text() (string, error) {
return delete.build.SimpleDelete(delete.name, delete.table, delete.where)
}
func (delete *deletePrebuilder) Parse() {
delete.build.SimpleDelete(delete.name, delete.table, delete.where)
}
type updatePrebuilder struct {
name string
table string
set string
where string
build Adapter
}
func (update *updatePrebuilder) Table(table string) *updatePrebuilder {
update.table = table
return update
}
func (update *updatePrebuilder) Set(set string) *updatePrebuilder {
update.set = set
return update
}
func (update *updatePrebuilder) Where(where string) *updatePrebuilder {
update.where = where
return update
}
func (update *updatePrebuilder) Text() (string, error) {
return update.build.SimpleUpdate(update.name, update.table, update.set, update.where)
}
func (update *updatePrebuilder) Parse() {
update.build.SimpleUpdate(update.name, update.table, update.set, update.where)
}
type selectPrebuilder struct {
name string
table string
columns string
where string
orderby string
limit string
build Adapter
}
func (selectItem *selectPrebuilder) Table(table string) *selectPrebuilder {
selectItem.table = table
return selectItem
}
func (selectItem *selectPrebuilder) Columns(columns string) *selectPrebuilder {
selectItem.columns = columns
return selectItem
}
func (selectItem *selectPrebuilder) Where(where string) *selectPrebuilder {
selectItem.where = where
return selectItem
}
func (selectItem *selectPrebuilder) Orderby(orderby string) *selectPrebuilder {
selectItem.orderby = orderby
return selectItem
}
func (selectItem *selectPrebuilder) Limit(limit string) *selectPrebuilder {
selectItem.limit = limit
return selectItem
}
func (selectItem *selectPrebuilder) Text() (string, error) {
return selectItem.build.SimpleSelect(selectItem.name, selectItem.table, selectItem.columns, selectItem.where, selectItem.orderby, selectItem.limit)
}
func (selectItem *selectPrebuilder) Parse() {
selectItem.build.SimpleSelect(selectItem.name, selectItem.table, selectItem.columns, selectItem.where, selectItem.orderby, selectItem.limit)
}
type insertPrebuilder struct {
name string
table string
columns string
fields string
build Adapter
}
func (insert *insertPrebuilder) Table(table string) *insertPrebuilder {
insert.table = table
return insert
}
func (insert *insertPrebuilder) Columns(columns string) *insertPrebuilder {
insert.columns = columns
return insert
}
func (insert *insertPrebuilder) Fields(fields string) *insertPrebuilder {
insert.fields = fields
return insert
}
func (insert *insertPrebuilder) Text() (string, error) {
return insert.build.SimpleInsert(insert.name, insert.table, insert.columns, insert.fields)
}
func (insert *insertPrebuilder) Parse() {
insert.build.SimpleInsert(insert.name, insert.table, insert.columns, insert.fields)
}
type countPrebuilder struct {
name string
table string
where string
limit string
build Adapter
}
func (count *countPrebuilder) Table(table string) *countPrebuilder {
count.table = table
return count
}
func (count *countPrebuilder) Where(where string) *countPrebuilder {
count.where = where
return count
}
func (count *countPrebuilder) Limit(limit string) *countPrebuilder {
count.limit = limit
return count
}
func (count *countPrebuilder) Text() (string, error) {
return count.build.SimpleCount(count.name, count.table, count.where, count.limit)
}
func (count *countPrebuilder) Parse() {
count.build.SimpleCount(count.name, count.table, count.where, count.limit)
}
func optString(nlist []string, defaultStr string) string {
if len(nlist) == 0 {
return defaultStr
}
return nlist[0]
}

View File

@ -9,14 +9,14 @@ import (
) )
func init() { func init() {
DB_Registry = append(DB_Registry, Registry = append(Registry,
&MssqlAdapter{Name: "mssql", Buffer: make(map[string]DB_Stmt)}, &MssqlAdapter{Name: "mssql", Buffer: make(map[string]DBStmt)},
) )
} }
type MssqlAdapter struct { type MssqlAdapter struct {
Name string // ? - Do we really need this? Can't we hard-code this? Name string // ? - Do we really need this? Can't we hard-code this?
Buffer map[string]DB_Stmt Buffer map[string]DBStmt
BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit
keys map[string]string keys map[string]string
} }
@ -26,17 +26,17 @@ func (adapter *MssqlAdapter) GetName() string {
return adapter.Name return adapter.Name
} }
func (adapter *MssqlAdapter) GetStmt(name string) DB_Stmt { func (adapter *MssqlAdapter) GetStmt(name string) DBStmt {
return adapter.Buffer[name] return adapter.Buffer[name]
} }
func (adapter *MssqlAdapter) GetStmts() map[string]DB_Stmt { func (adapter *MssqlAdapter) GetStmts() map[string]DBStmt {
return adapter.Buffer return adapter.Buffer
} }
// TODO: Convert any remaining stringy types to nvarchar // TODO: Convert any remaining stringy types to nvarchar
// We may need to change the CreateTable API to better suit Mssql and the other database drivers which are coming up // We may need to change the CreateTable API to better suit Mssql and the other database drivers which are coming up
func (adapter *MssqlAdapter) CreateTable(name string, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (string, error) { func (adapter *MssqlAdapter) CreateTable(name string, table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (string, error) {
if name == "" { if name == "" {
return "", errors.New("You need a name for this statement") return "", errors.New("You need a name for this statement")
} }
@ -89,7 +89,7 @@ func (adapter *MssqlAdapter) CreateTable(name string, table string, charset stri
} }
// ! Not exactly the meaning of auto increment... // ! Not exactly the meaning of auto increment...
if column.Auto_Increment { if column.AutoIncrement {
end += " IDENTITY" end += " IDENTITY"
} }
@ -770,7 +770,7 @@ func (adapter *MssqlAdapter) SimpleInnerJoin(name string, table1 string, table2
return querystr, nil return querystr, nil
} }
func (adapter *MssqlAdapter) SimpleInsertSelect(name string, ins DB_Insert, sel DB_Select) (string, error) { func (adapter *MssqlAdapter) SimpleInsertSelect(name string, ins DBInsert, sel DBSelect) (string, error) {
// TODO: More errors. // TODO: More errors.
// TODO: Add this to the MySQL adapter in order to make this problem more discoverable? // TODO: Add this to the MySQL adapter in order to make this problem more discoverable?
if len(sel.Orderby) == 0 && sel.Limit != "" { if len(sel.Orderby) == 0 && sel.Limit != "" {
@ -885,7 +885,7 @@ func (adapter *MssqlAdapter) SimpleInsertSelect(name string, ins DB_Insert, sel
return querystr, nil return querystr, nil
} }
func (adapter *MssqlAdapter) simpleJoin(name string, ins DB_Insert, sel DB_Join, joinType string) (string, error) { func (adapter *MssqlAdapter) simpleJoin(name string, ins DBInsert, sel DBJoin, joinType string) (string, error) {
// TODO: More errors. // TODO: More errors.
// TODO: Add this to the MySQL adapter in order to make this problem more discoverable? // TODO: Add this to the MySQL adapter in order to make this problem more discoverable?
if len(sel.Orderby) == 0 && sel.Limit != "" { if len(sel.Orderby) == 0 && sel.Limit != "" {
@ -1015,11 +1015,11 @@ func (adapter *MssqlAdapter) simpleJoin(name string, ins DB_Insert, sel DB_Join,
return querystr, nil return querystr, nil
} }
func (adapter *MssqlAdapter) SimpleInsertLeftJoin(name string, ins DB_Insert, sel DB_Join) (string, error) { func (adapter *MssqlAdapter) SimpleInsertLeftJoin(name string, ins DBInsert, sel DBJoin) (string, error) {
return adapter.simpleJoin(name, ins, sel, "LEFT") return adapter.simpleJoin(name, ins, sel, "LEFT")
} }
func (adapter *MssqlAdapter) SimpleInsertInnerJoin(name string, ins DB_Insert, sel DB_Join) (string, error) { func (adapter *MssqlAdapter) SimpleInsertInnerJoin(name string, ins DBInsert, sel DBJoin) (string, error) {
return adapter.simpleJoin(name, ins, sel, "INNER") return adapter.simpleJoin(name, ins, sel, "INNER")
} }
@ -1036,9 +1036,6 @@ func (adapter *MssqlAdapter) SimpleCount(name string, table string, where string
// TODO: Add support for BETWEEN x.x // TODO: Add support for BETWEEN x.x
if len(where) != 0 { if len(where) != 0 {
querystr += " WHERE" querystr += " WHERE"
//fmt.Println("SimpleCount:",name)
//fmt.Println("where:",where)
//fmt.Println("processWhere:",processWhere(where))
for _, loc := range processWhere(where) { for _, loc := range processWhere(where) {
for _, token := range loc.Expr { for _, token := range loc.Expr {
switch token.Type { switch token.Type {
@ -1069,6 +1066,11 @@ func (adapter *MssqlAdapter) SimpleCount(name string, table string, where string
return querystr, nil return querystr, nil
} }
func (adapter *MssqlAdapter) Select(nlist ...string) *selectPrebuilder {
name := optString(nlist, "_builder")
return &selectPrebuilder{name, "", "", "", "", "", adapter}
}
func (adapter *MssqlAdapter) Write() error { func (adapter *MssqlAdapter) Write() error {
var stmts, body string var stmts, body string
for _, name := range adapter.BufferOrder { for _, name := range adapter.BufferOrder {
@ -1130,7 +1132,7 @@ func _gen_mssql() (err error) {
// Internal methods, not exposed in the interface // Internal methods, not exposed in the interface
func (adapter *MssqlAdapter) pushStatement(name string, stype string, querystr string) { func (adapter *MssqlAdapter) pushStatement(name string, stype string, querystr string) {
adapter.Buffer[name] = DB_Stmt{querystr, stype} adapter.Buffer[name] = DBStmt{querystr, stype}
adapter.BufferOrder = append(adapter.BufferOrder, name) adapter.BufferOrder = append(adapter.BufferOrder, name)
} }

View File

@ -7,14 +7,14 @@ import "strconv"
import "errors" import "errors"
func init() { func init() {
DB_Registry = append(DB_Registry, Registry = append(Registry,
&MysqlAdapter{Name: "mysql", Buffer: make(map[string]DB_Stmt)}, &MysqlAdapter{Name: "mysql", Buffer: make(map[string]DBStmt)},
) )
} }
type MysqlAdapter struct { type MysqlAdapter struct {
Name string // ? - Do we really need this? Can't we hard-code this? Name string // ? - Do we really need this? Can't we hard-code this?
Buffer map[string]DB_Stmt Buffer map[string]DBStmt
BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit
} }
@ -23,15 +23,15 @@ func (adapter *MysqlAdapter) GetName() string {
return adapter.Name return adapter.Name
} }
func (adapter *MysqlAdapter) GetStmt(name string) DB_Stmt { func (adapter *MysqlAdapter) GetStmt(name string) DBStmt {
return adapter.Buffer[name] return adapter.Buffer[name]
} }
func (adapter *MysqlAdapter) GetStmts() map[string]DB_Stmt { func (adapter *MysqlAdapter) GetStmts() map[string]DBStmt {
return adapter.Buffer return adapter.Buffer
} }
func (adapter *MysqlAdapter) CreateTable(name string, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (string, error) { func (adapter *MysqlAdapter) CreateTable(name string, table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (string, error) {
if name == "" { if name == "" {
return "", errors.New("You need a name for this statement") return "", errors.New("You need a name for this statement")
} }
@ -71,7 +71,7 @@ func (adapter *MysqlAdapter) CreateTable(name string, table string, charset stri
end += " not null" end += " not null"
} }
if column.Auto_Increment { if column.AutoIncrement {
end += " AUTO_INCREMENT" end += " AUTO_INCREMENT"
} }
@ -430,7 +430,7 @@ func (adapter *MysqlAdapter) SimpleInnerJoin(name string, table1 string, table2
return querystr, nil return querystr, nil
} }
func (adapter *MysqlAdapter) SimpleInsertSelect(name string, ins DB_Insert, sel DB_Select) (string, error) { func (adapter *MysqlAdapter) SimpleInsertSelect(name string, ins DBInsert, sel DBSelect) (string, error) {
whereStr, err := adapter.buildWhere(sel.Where) whereStr, err := adapter.buildWhere(sel.Where)
if err != nil { if err != nil {
return "", err return "", err
@ -443,7 +443,7 @@ func (adapter *MysqlAdapter) SimpleInsertSelect(name string, ins DB_Insert, sel
return querystr, nil return querystr, nil
} }
func (adapter *MysqlAdapter) SimpleInsertLeftJoin(name string, ins DB_Insert, sel DB_Join) (string, error) { func (adapter *MysqlAdapter) SimpleInsertLeftJoin(name string, ins DBInsert, sel DBJoin) (string, error) {
whereStr, err := adapter.buildJoinWhere(sel.Where) whereStr, err := adapter.buildJoinWhere(sel.Where)
if err != nil { if err != nil {
return "", err return "", err
@ -520,7 +520,7 @@ func (adapter *MysqlAdapter) buildJoinColumns(columns string) (querystr string)
return querystr[0 : len(querystr)-1] return querystr[0 : len(querystr)-1]
} }
func (adapter *MysqlAdapter) SimpleInsertInnerJoin(name string, ins DB_Insert, sel DB_Join) (string, error) { func (adapter *MysqlAdapter) SimpleInsertInnerJoin(name string, ins DBInsert, sel DBJoin) (string, error) {
whereStr, err := adapter.buildJoinWhere(sel.Where) whereStr, err := adapter.buildJoinWhere(sel.Where)
if err != nil { if err != nil {
return "", err return "", err
@ -552,6 +552,11 @@ func (adapter *MysqlAdapter) SimpleCount(name string, table string, where string
return querystr, nil return querystr, nil
} }
func (adapter *MysqlAdapter) Select(nlist ...string) *selectPrebuilder {
name := optString(nlist, "_builder")
return &selectPrebuilder{name, "", "", "", "", "", adapter}
}
func (adapter *MysqlAdapter) Write() error { func (adapter *MysqlAdapter) Write() error {
var stmts, body string var stmts, body string
for _, name := range adapter.BufferOrder { for _, name := range adapter.BufferOrder {
@ -623,7 +628,7 @@ func _gen_mysql() (err error) {
// Internal methods, not exposed in the interface // Internal methods, not exposed in the interface
func (adapter *MysqlAdapter) pushStatement(name string, stype string, querystr string) { func (adapter *MysqlAdapter) pushStatement(name string, stype string, querystr string) {
adapter.Buffer[name] = DB_Stmt{querystr, stype} adapter.Buffer[name] = DBStmt{querystr, stype}
adapter.BufferOrder = append(adapter.BufferOrder, name) adapter.BufferOrder = append(adapter.BufferOrder, name)
} }

View File

@ -6,14 +6,14 @@ import "strconv"
import "errors" import "errors"
func init() { func init() {
DB_Registry = append(DB_Registry, Registry = append(Registry,
&PgsqlAdapter{Name: "pgsql", Buffer: make(map[string]DB_Stmt)}, &PgsqlAdapter{Name: "pgsql", Buffer: make(map[string]DBStmt)},
) )
} }
type PgsqlAdapter struct { type PgsqlAdapter struct {
Name string // ? - Do we really need this? Can't we hard-code this? Name string // ? - Do we really need this? Can't we hard-code this?
Buffer map[string]DB_Stmt Buffer map[string]DBStmt
BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit BufferOrder []string // Map iteration order is random, so we need this to track the order, so we don't get huge diffs every commit
} }
@ -22,17 +22,17 @@ func (adapter *PgsqlAdapter) GetName() string {
return adapter.Name return adapter.Name
} }
func (adapter *PgsqlAdapter) GetStmt(name string) DB_Stmt { func (adapter *PgsqlAdapter) GetStmt(name string) DBStmt {
return adapter.Buffer[name] return adapter.Buffer[name]
} }
func (adapter *PgsqlAdapter) GetStmts() map[string]DB_Stmt { func (adapter *PgsqlAdapter) GetStmts() map[string]DBStmt {
return adapter.Buffer return adapter.Buffer
} }
// TODO: Implement this // TODO: Implement this
// We may need to change the CreateTable API to better suit PGSQL and the other database drivers which are coming up // We may need to change the CreateTable API to better suit PGSQL and the other database drivers which are coming up
func (adapter *PgsqlAdapter) CreateTable(name string, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (string, error) { func (adapter *PgsqlAdapter) CreateTable(name string, table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (string, error) {
if name == "" { if name == "" {
return "", errors.New("You need a name for this statement") return "", errors.New("You need a name for this statement")
} }
@ -45,7 +45,7 @@ func (adapter *PgsqlAdapter) CreateTable(name string, table string, charset stri
var querystr = "CREATE TABLE `" + table + "` (" var querystr = "CREATE TABLE `" + table + "` ("
for _, column := range columns { for _, column := range columns {
if column.Auto_Increment { if column.AutoIncrement {
column.Type = "serial" column.Type = "serial"
} else if column.Type == "createdAt" { } else if column.Type == "createdAt" {
column.Type = "timestamp" column.Type = "timestamp"
@ -293,17 +293,17 @@ func (adapter *PgsqlAdapter) SimpleInnerJoin(name string, table1 string, table2
} }
// TODO: Implement this // TODO: Implement this
func (adapter *PgsqlAdapter) SimpleInsertSelect(name string, ins DB_Insert, sel DB_Select) (string, error) { func (adapter *PgsqlAdapter) SimpleInsertSelect(name string, ins DBInsert, sel DBSelect) (string, error) {
return "", nil return "", nil
} }
// TODO: Implement this // TODO: Implement this
func (adapter *PgsqlAdapter) SimpleInsertLeftJoin(name string, ins DB_Insert, sel DB_Join) (string, error) { func (adapter *PgsqlAdapter) SimpleInsertLeftJoin(name string, ins DBInsert, sel DBJoin) (string, error) {
return "", nil return "", nil
} }
// TODO: Implement this // TODO: Implement this
func (adapter *PgsqlAdapter) SimpleInsertInnerJoin(name string, ins DB_Insert, sel DB_Join) (string, error) { func (adapter *PgsqlAdapter) SimpleInsertInnerJoin(name string, ins DBInsert, sel DBJoin) (string, error) {
return "", nil return "", nil
} }
@ -318,6 +318,11 @@ func (adapter *PgsqlAdapter) SimpleCount(name string, table string, where string
return "", nil return "", nil
} }
func (adapter *PgsqlAdapter) Select(nlist ...string) *selectPrebuilder {
name := optString(nlist, "_builder")
return &selectPrebuilder{name, "", "", "", "", "", adapter}
}
func (adapter *PgsqlAdapter) Write() error { func (adapter *PgsqlAdapter) Write() error {
var stmts, body string var stmts, body string
for _, name := range adapter.BufferOrder { for _, name := range adapter.BufferOrder {
@ -378,7 +383,7 @@ func _gen_pgsql() (err error) {
// Internal methods, not exposed in the interface // Internal methods, not exposed in the interface
func (adapter *PgsqlAdapter) pushStatement(name string, stype string, querystr string) { func (adapter *PgsqlAdapter) pushStatement(name string, stype string, querystr string) {
adapter.Buffer[name] = DB_Stmt{querystr, stype} adapter.Buffer[name] = DBStmt{querystr, stype}
adapter.BufferOrder = append(adapter.BufferOrder, name) adapter.BufferOrder = append(adapter.BufferOrder, name)
} }

View File

@ -6,24 +6,24 @@ import (
"errors" "errors"
) )
var DB_Registry []DB_Adapter var Registry []Adapter
var ErrNoAdapter = errors.New("This adapter doesn't exist") var ErrNoAdapter = errors.New("This adapter doesn't exist")
type DB_Table_Column struct { type DBTableColumn struct {
Name string Name string
Type string Type string
Size int Size int
Null bool Null bool
Auto_Increment bool AutoIncrement bool
Default string Default string
} }
type DB_Table_Key struct { type DBTableKey struct {
Columns string Columns string
Type string Type string
} }
type DB_Select struct { type DBSelect struct {
Table string Table string
Columns string Columns string
Where string Where string
@ -31,7 +31,7 @@ type DB_Select struct {
Limit string Limit string
} }
type DB_Join struct { type DBJoin struct {
Table1 string Table1 string
Table2 string Table2 string
Columns string Columns string
@ -41,29 +41,29 @@ type DB_Join struct {
Limit string Limit string
} }
type DB_Insert struct { type DBInsert struct {
Table string Table string
Columns string Columns string
Fields string Fields string
} }
type DB_Column struct { type DBColumn struct {
Table string Table string
Left string // Could be a function or a column, so I'm naming this Left Left string // Could be a function or a column, so I'm naming this Left
Alias string // aka AS Blah, if it's present Alias string // aka AS Blah, if it's present
Type string // function or column Type string // function or column
} }
type DB_Field struct { type DBField struct {
Name string Name string
Type string Type string
} }
type DB_Where struct { type DBWhere struct {
Expr []DB_Token // Simple expressions, the innards of functions are opaque for now. Expr []DBToken // Simple expressions, the innards of functions are opaque for now.
} }
type DB_Joiner struct { type DBJoiner struct {
LeftTable string LeftTable string
LeftColumn string LeftColumn string
RightTable string RightTable string
@ -71,34 +71,34 @@ type DB_Joiner struct {
Operator string Operator string
} }
type DB_Order struct { type DBOrder struct {
Column string Column string
Order string Order string
} }
type DB_Token struct { type DBToken struct {
Contents string Contents string
Type string // function, operator, column, number, string, substitute Type string // function, operator, column, number, string, substitute
} }
type DB_Setter struct { type DBSetter struct {
Column string Column string
Expr []DB_Token // Simple expressions, the innards of functions are opaque for now. Expr []DBToken // Simple expressions, the innards of functions are opaque for now.
} }
type DB_Limit struct { type DBLimit struct {
Offset string // ? or int Offset string // ? or int
MaxCount string // ? or int MaxCount string // ? or int
} }
type DB_Stmt struct { type DBStmt struct {
Contents string Contents string
Type string // create-table, insert, update, delete Type string // create-table, insert, update, delete
} }
type DB_Adapter interface { type Adapter interface {
GetName() string GetName() string
CreateTable(name string, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (string, error) CreateTable(name string, table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) (string, error)
SimpleInsert(name string, table string, columns string, fields string) (string, error) SimpleInsert(name string, table string, columns string, fields string) (string, error)
// ! DEPRECATED // ! DEPRECATED
@ -111,17 +111,19 @@ type DB_Adapter interface {
SimpleSelect(name string, table string, columns string, where string, orderby string, limit string) (string, error) SimpleSelect(name string, table string, columns string, where string, orderby string, limit string) (string, error)
SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error) SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error)
SimpleInnerJoin(string, string, string, string, string, string, string, string) (string, error) SimpleInnerJoin(string, string, string, string, string, string, string, string) (string, error)
SimpleInsertSelect(string, DB_Insert, DB_Select) (string, error) SimpleInsertSelect(string, DBInsert, DBSelect) (string, error)
SimpleInsertLeftJoin(string, DB_Insert, DB_Join) (string, error) SimpleInsertLeftJoin(string, DBInsert, DBJoin) (string, error)
SimpleInsertInnerJoin(string, DB_Insert, DB_Join) (string, error) SimpleInsertInnerJoin(string, DBInsert, DBJoin) (string, error)
SimpleCount(string, string, string, string) (string, error) SimpleCount(string, string, string, string) (string, error)
Select(name ...string) *selectPrebuilder
Write() error Write() error
// TODO: Add a simple query builder // TODO: Add a simple query builder
} }
func GetAdapter(name string) (adap DB_Adapter, err error) { func GetAdapter(name string) (adap Adapter, err error) {
for _, adapter := range DB_Registry { for _, adapter := range Registry {
if adapter.GetName() == name { if adapter.GetName() == name {
return adapter, nil return adapter, nil
} }

View File

@ -20,7 +20,7 @@ func (stmt *transactionStmt) Exec(args ...interface{}) (*sql.Result, error) {
type TransactionBuilder struct { type TransactionBuilder struct {
tx *sql.Tx tx *sql.Tx
adapter DB_Adapter adapter Adapter
textToStmt map[string]*transactionStmt textToStmt map[string]*transactionStmt
} }

View File

@ -13,13 +13,13 @@ import (
"strings" "strings"
) )
func processColumns(colstr string) (columns []DB_Column) { func processColumns(colstr string) (columns []DBColumn) {
if colstr == "" { if colstr == "" {
return columns return columns
} }
colstr = strings.Replace(colstr, " as ", " AS ", -1) colstr = strings.Replace(colstr, " as ", " AS ", -1)
for _, segment := range strings.Split(colstr, ",") { for _, segment := range strings.Split(colstr, ",") {
var outcol DB_Column var outcol DBColumn
dotHalves := strings.Split(strings.TrimSpace(segment), ".") dotHalves := strings.Split(strings.TrimSpace(segment), ".")
var halves []string var halves []string
@ -49,12 +49,12 @@ func processColumns(colstr string) (columns []DB_Column) {
} }
// TODO: Allow order by statements without a direction // TODO: Allow order by statements without a direction
func processOrderby(orderstr string) (order []DB_Order) { func processOrderby(orderstr string) (order []DBOrder) {
if orderstr == "" { if orderstr == "" {
return order return order
} }
for _, segment := range strings.Split(orderstr, ",") { for _, segment := range strings.Split(orderstr, ",") {
var outorder DB_Order var outorder DBOrder
halves := strings.Split(strings.TrimSpace(segment), " ") halves := strings.Split(strings.TrimSpace(segment), " ")
if len(halves) != 2 { if len(halves) != 2 {
continue continue
@ -66,14 +66,14 @@ func processOrderby(orderstr string) (order []DB_Order) {
return order return order
} }
func processJoiner(joinstr string) (joiner []DB_Joiner) { func processJoiner(joinstr string) (joiner []DBJoiner) {
if joinstr == "" { if joinstr == "" {
return joiner return joiner
} }
joinstr = strings.Replace(joinstr, " on ", " ON ", -1) joinstr = strings.Replace(joinstr, " on ", " ON ", -1)
joinstr = strings.Replace(joinstr, " and ", " AND ", -1) joinstr = strings.Replace(joinstr, " and ", " AND ", -1)
for _, segment := range strings.Split(joinstr, " AND ") { for _, segment := range strings.Split(joinstr, " AND ") {
var outjoin DB_Joiner var outjoin DBJoiner
var parseOffset int var parseOffset int
var left, right string var left, right string
@ -93,7 +93,7 @@ func processJoiner(joinstr string) (joiner []DB_Joiner) {
return joiner return joiner
} }
func processWhere(wherestr string) (where []DB_Where) { func processWhere(wherestr string) (where []DBWhere) {
if wherestr == "" { if wherestr == "" {
return where return where
} }
@ -102,7 +102,7 @@ func processWhere(wherestr string) (where []DB_Where) {
var buffer string var buffer string
var optype int // 0: None, 1: Number, 2: Column, 3: Function, 4: String, 5: Operator var optype int // 0: None, 1: Number, 2: Column, 3: Function, 4: String, 5: Operator
for _, segment := range strings.Split(wherestr, " AND ") { for _, segment := range strings.Split(wherestr, " AND ") {
var tmpWhere DB_Where var tmpWhere DBWhere
segment += ")" segment += ")"
for i := 0; i < len(segment); i++ { for i := 0; i < len(segment); i++ {
char := segment[i] char := segment[i]
@ -124,7 +124,7 @@ func processWhere(wherestr string) (where []DB_Where) {
buffer = string(char) buffer = string(char)
} else if char == '?' { } else if char == '?' {
//fmt.Println("Expr:","?") //fmt.Println("Expr:","?")
tmpWhere.Expr = append(tmpWhere.Expr, DB_Token{"?", "substitute"}) tmpWhere.Expr = append(tmpWhere.Expr, DBToken{"?", "substitute"})
} }
case 1: // number case 1: // number
if '0' <= char && char <= '9' { if '0' <= char && char <= '9' {
@ -133,7 +133,7 @@ func processWhere(wherestr string) (where []DB_Where) {
optype = 0 optype = 0
i-- i--
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpWhere.Expr = append(tmpWhere.Expr, DB_Token{buffer, "number"}) tmpWhere.Expr = append(tmpWhere.Expr, DBToken{buffer, "number"})
} }
case 2: // column case 2: // column
if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '.' || char == '_' { if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '.' || char == '_' {
@ -145,7 +145,7 @@ func processWhere(wherestr string) (where []DB_Where) {
optype = 0 optype = 0
i-- i--
//fmt.Println("Expr:", buffer) //fmt.Println("Expr:", buffer)
tmpWhere.Expr = append(tmpWhere.Expr, DB_Token{buffer, "column"}) tmpWhere.Expr = append(tmpWhere.Expr, DBToken{buffer, "column"})
} }
case 3: // function case 3: // function
var preI = i var preI = i
@ -160,7 +160,7 @@ func processWhere(wherestr string) (where []DB_Where) {
//fmt.Println("string(i)", string(halves[1][i])) //fmt.Println("string(i)", string(halves[1][i]))
buffer += segment[preI:i] + string(segment[i]) buffer += segment[preI:i] + string(segment[i])
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpWhere.Expr = append(tmpWhere.Expr, DB_Token{buffer, "function"}) tmpWhere.Expr = append(tmpWhere.Expr, DBToken{buffer, "function"})
optype = 0 optype = 0
case 4: // string case 4: // string
if char != '\'' { if char != '\'' {
@ -168,7 +168,7 @@ func processWhere(wherestr string) (where []DB_Where) {
} else { } else {
optype = 0 optype = 0
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpWhere.Expr = append(tmpWhere.Expr, DB_Token{buffer, "string"}) tmpWhere.Expr = append(tmpWhere.Expr, DBToken{buffer, "string"})
} }
case 5: // operator case 5: // operator
if isOpByte(char) { if isOpByte(char) {
@ -177,10 +177,10 @@ func processWhere(wherestr string) (where []DB_Where) {
optype = 0 optype = 0
i-- i--
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpWhere.Expr = append(tmpWhere.Expr, DB_Token{buffer, "operator"}) tmpWhere.Expr = append(tmpWhere.Expr, DBToken{buffer, "operator"})
} }
default: default:
panic("Bad optype in _process_where") panic("Bad optype in processWhere")
} }
} }
where = append(where, tmpWhere) where = append(where, tmpWhere)
@ -188,11 +188,10 @@ func processWhere(wherestr string) (where []DB_Where) {
return where return where
} }
func processSet(setstr string) (setter []DB_Setter) { func processSet(setstr string) (setter []DBSetter) {
if setstr == "" { if setstr == "" {
return setter return setter
} }
//fmt.Println("setstr",setstr)
// First pass, splitting the string by commas while ignoring the innards of functions // First pass, splitting the string by commas while ignoring the innards of functions
var setset []string var setset []string
@ -217,7 +216,7 @@ func processSet(setstr string) (setter []DB_Setter) {
// Second pass. Break this setitem into manageable chunks // Second pass. Break this setitem into manageable chunks
buffer = "" buffer = ""
for _, setitem := range setset { for _, setitem := range setset {
var tmpSetter DB_Setter var tmpSetter DBSetter
halves := strings.Split(setitem, "=") halves := strings.Split(setitem, "=")
if len(halves) != 2 { if len(halves) != 2 {
continue continue
@ -246,7 +245,7 @@ func processSet(setstr string) (setter []DB_Setter) {
buffer = string(char) buffer = string(char)
} else if char == '?' { } else if char == '?' {
//fmt.Println("Expr:","?") //fmt.Println("Expr:","?")
tmpSetter.Expr = append(tmpSetter.Expr, DB_Token{"?", "substitute"}) tmpSetter.Expr = append(tmpSetter.Expr, DBToken{"?", "substitute"})
} }
case 1: // number case 1: // number
if '0' <= char && char <= '9' { if '0' <= char && char <= '9' {
@ -255,7 +254,7 @@ func processSet(setstr string) (setter []DB_Setter) {
optype = 0 optype = 0
i-- i--
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpSetter.Expr = append(tmpSetter.Expr, DB_Token{buffer, "number"}) tmpSetter.Expr = append(tmpSetter.Expr, DBToken{buffer, "number"})
} }
case 2: // column case 2: // column
if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_' { if ('a' <= char && char <= 'z') || ('A' <= char && char <= 'Z') || char == '_' {
@ -267,7 +266,7 @@ func processSet(setstr string) (setter []DB_Setter) {
optype = 0 optype = 0
i-- i--
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpSetter.Expr = append(tmpSetter.Expr, DB_Token{buffer, "column"}) tmpSetter.Expr = append(tmpSetter.Expr, DBToken{buffer, "column"})
} }
case 3: // function case 3: // function
var preI = i var preI = i
@ -282,7 +281,7 @@ func processSet(setstr string) (setter []DB_Setter) {
//fmt.Println("string(i)",string(halves[1][i])) //fmt.Println("string(i)",string(halves[1][i]))
buffer += halves[1][preI:i] + string(halves[1][i]) buffer += halves[1][preI:i] + string(halves[1][i])
//fmt.Println("Expr:",buffer) //fmt.Println("Expr:",buffer)
tmpSetter.Expr = append(tmpSetter.Expr, DB_Token{buffer, "function"}) tmpSetter.Expr = append(tmpSetter.Expr, DBToken{buffer, "function"})
optype = 0 optype = 0
case 4: // string case 4: // string
if char != '\'' { if char != '\'' {
@ -290,7 +289,7 @@ func processSet(setstr string) (setter []DB_Setter) {
} else { } else {
optype = 0 optype = 0
//fmt.Println("Expr:", buffer) //fmt.Println("Expr:", buffer)
tmpSetter.Expr = append(tmpSetter.Expr, DB_Token{buffer, "string"}) tmpSetter.Expr = append(tmpSetter.Expr, DBToken{buffer, "string"})
} }
case 5: // operator case 5: // operator
if isOpByte(char) { if isOpByte(char) {
@ -299,7 +298,7 @@ func processSet(setstr string) (setter []DB_Setter) {
optype = 0 optype = 0
i-- i--
//fmt.Println("Expr:", buffer) //fmt.Println("Expr:", buffer)
tmpSetter.Expr = append(tmpSetter.Expr, DB_Token{buffer, "operator"}) tmpSetter.Expr = append(tmpSetter.Expr, DBToken{buffer, "operator"})
} }
default: default:
panic("Bad optype in processSet") panic("Bad optype in processSet")
@ -307,11 +306,10 @@ func processSet(setstr string) (setter []DB_Setter) {
} }
setter = append(setter, tmpSetter) setter = append(setter, tmpSetter)
} }
//fmt.Println("setter",setter)
return setter return setter
} }
func processLimit(limitstr string) (limiter DB_Limit) { func processLimit(limitstr string) (limiter DBLimit) {
halves := strings.Split(limitstr, ",") halves := strings.Split(limitstr, ",")
if len(halves) == 2 { if len(halves) == 2 {
limiter.Offset = halves[0] limiter.Offset = halves[0]
@ -330,7 +328,7 @@ func isOpRune(char rune) bool {
return char == '<' || char == '>' || char == '=' || char == '!' || char == '*' || char == '%' || char == '+' || char == '-' || char == '/' return char == '<' || char == '>' || char == '=' || char == '!' || char == '*' || char == '%' || char == '+' || char == '-' || char == '/'
} }
func processFields(fieldstr string) (fields []DB_Field) { func processFields(fieldstr string) (fields []DBField) {
if fieldstr == "" { if fieldstr == "" {
return fields return fields
} }
@ -340,11 +338,11 @@ func processFields(fieldstr string) (fields []DB_Field) {
for i := 0; i < len(fieldstr); i++ { for i := 0; i < len(fieldstr); i++ {
if fieldstr[i] == '(' { if fieldstr[i] == '(' {
i = skipFunctionCall(fieldstr, i-1) i = skipFunctionCall(fieldstr, i-1)
fields = append(fields, DB_Field{Name: fieldstr[lastItem : i+1], Type: getIdentifierType(fieldstr[lastItem : i+1])}) fields = append(fields, DBField{Name: fieldstr[lastItem : i+1], Type: getIdentifierType(fieldstr[lastItem : i+1])})
buffer = "" buffer = ""
lastItem = i + 2 lastItem = i + 2
} else if fieldstr[i] == ',' && buffer != "" { } else if fieldstr[i] == ',' && buffer != "" {
fields = append(fields, DB_Field{Name: buffer, Type: getIdentifierType(buffer)}) fields = append(fields, DBField{Name: buffer, Type: getIdentifierType(buffer)})
buffer = "" buffer = ""
lastItem = i + 1 lastItem = i + 1
} else if (fieldstr[i] > 32) && fieldstr[i] != ',' && fieldstr[i] != ')' { } else if (fieldstr[i] > 32) && fieldstr[i] != ',' && fieldstr[i] != ')' {

View File

@ -23,8 +23,8 @@ func main() {
}() }()
log.Println("Running the query generator") log.Println("Running the query generator")
for _, adapter := range qgen.DB_Registry { for _, adapter := range qgen.Registry {
log.Println("Building the queries for the " + adapter.GetName() + " adapter") log.Printf("Building the queries for the %s adapter", adapter.GetName())
qgen.Install.SetAdapterInstance(adapter) qgen.Install.SetAdapterInstance(adapter)
qgen.Install.RegisterPlugin(NewPrimaryKeySpitter()) // TODO: Do we really need to fill the spitter for every adapter? qgen.Install.RegisterPlugin(NewPrimaryKeySpitter()) // TODO: Do we really need to fill the spitter for every adapter?
@ -44,7 +44,7 @@ func main() {
} }
// nolint // nolint
func writeStatements(adapter qgen.DB_Adapter) error { func writeStatements(adapter qgen.Adapter) error {
err := createTables(adapter) err := createTables(adapter)
if err != nil { if err != nil {
return err return err
@ -118,7 +118,7 @@ func writeStatements(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func seedTables(adapter qgen.DB_Adapter) error { func seedTables(adapter qgen.Adapter) error {
qgen.Install.SimpleInsert("sync", "last_update", "UTC_TIMESTAMP()") qgen.Install.SimpleInsert("sync", "last_update", "UTC_TIMESTAMP()")
qgen.Install.SimpleInsert("settings", "name, content, type", "'url_tags','1','bool'") qgen.Install.SimpleInsert("settings", "name, content, type", "'url_tags','1','bool'")
@ -219,22 +219,22 @@ func seedTables(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeSelects(adapter qgen.DB_Adapter) error { func writeSelects(adapter qgen.Adapter) error {
// Looking for getTopic? Your statement is in another castle // Looking for getTopic? Your statement is in another castle
adapter.SimpleSelect("getPassword", "users", "password, salt", "uid = ?", "", "") adapter.Select("getPassword").Table("users").Columns("password, salt").Where("uid = ?").Parse()
adapter.SimpleSelect("getSettings", "settings", "name, content, type", "", "", "") adapter.Select("getSettings").Table("settings").Columns("name, content, type").Parse()
adapter.SimpleSelect("getSetting", "settings", "content, type", "name = ?", "", "") adapter.Select("getSetting").Table("settings").Columns("content, type").Where("name = ?").Parse()
adapter.SimpleSelect("getFullSetting", "settings", "name, type, constraints", "name = ?", "", "") adapter.Select("getFullSetting").Table("settings").Columns("name, type, constraints").Where("name = ?").Parse()
adapter.SimpleSelect("isPluginActive", "plugins", "active", "uname = ?", "", "") adapter.Select("isPluginActive").Table("plugins").Columns("active").Where("uname = ?").Parse()
//adapter.SimpleSelect("isPluginInstalled","plugins","installed","uname = ?","","") //adapter.SimpleSelect("isPluginInstalled","plugins","installed","uname = ?","","")
adapter.SimpleSelect("getUsersOffset", "users", "uid, name, group, active, is_super_admin, avatar", "", "uid ASC", "?,?") adapter.Select("getUsersOffset").Table("users").Columns("uid, name, group, active, is_super_admin, avatar").Orderby("uid ASC").Limit("?,?").Parse()
adapter.SimpleSelect("isThemeDefault", "themes", "default", "uname = ?", "", "") adapter.SimpleSelect("isThemeDefault", "themes", "default", "uname = ?", "", "")
@ -267,7 +267,7 @@ func writeSelects(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeLeftJoins(adapter qgen.DB_Adapter) error { func writeLeftJoins(adapter qgen.Adapter) error {
adapter.SimpleLeftJoin("getTopicRepliesOffset", "replies", "users", "replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress, replies.likeCount, replies.actionType", "replies.createdBy = users.uid", "replies.tid = ?", "replies.rid ASC", "?,?") adapter.SimpleLeftJoin("getTopicRepliesOffset", "replies", "users", "replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress, replies.likeCount, replies.actionType", "replies.createdBy = users.uid", "replies.tid = ?", "replies.rid ASC", "?,?")
adapter.SimpleLeftJoin("getTopicList", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC", "") adapter.SimpleLeftJoin("getTopicList", "topics", "users", "topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar", "topics.createdBy = users.uid", "", "topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC", "")
@ -281,7 +281,7 @@ func writeLeftJoins(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeInnerJoins(adapter qgen.DB_Adapter) (err error) { func writeInnerJoins(adapter qgen.Adapter) (err error) {
_, err = adapter.SimpleInnerJoin("getWatchers", "activity_stream", "activity_subscriptions", "activity_subscriptions.user", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", "") _, err = adapter.SimpleInnerJoin("getWatchers", "activity_stream", "activity_subscriptions", "activity_subscriptions.user", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", "")
if err != nil { if err != nil {
return err return err
@ -290,7 +290,7 @@ func writeInnerJoins(adapter qgen.DB_Adapter) (err error) {
return nil return nil
} }
func writeInserts(adapter qgen.DB_Adapter) error { func writeInserts(adapter qgen.Adapter) error {
adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'") adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'")
adapter.SimpleInsert("addActivity", "activity_stream", "actor, targetUser, event, elementType, elementID", "?,?,?,?,?") adapter.SimpleInsert("addActivity", "activity_stream", "actor, targetUser, event, elementType, elementID", "?,?,?,?,?")
@ -314,12 +314,12 @@ func writeInserts(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeReplaces(adapter qgen.DB_Adapter) (err error) { func writeReplaces(adapter qgen.Adapter) (err error) {
return nil return nil
} }
// ! Upserts are broken atm // ! Upserts are broken atm
/*func writeUpserts(adapter qgen.DB_Adapter) (err error) { /*func writeUpserts(adapter qgen.Adapter) (err error) {
_, err = adapter.SimpleUpsert("addForumPermsToGroup", "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?", "gid = ? AND fid = ?") _, err = adapter.SimpleUpsert("addForumPermsToGroup", "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?", "gid = ? AND fid = ?")
if err != nil { if err != nil {
return err return err
@ -333,7 +333,7 @@ func writeReplaces(adapter qgen.DB_Adapter) (err error) {
return nil return nil
}*/ }*/
func writeUpdates(adapter qgen.DB_Adapter) error { func writeUpdates(adapter qgen.Adapter) error {
adapter.SimpleUpdate("editReply", "replies", "content = ?, parsed_content = ?", "rid = ?") adapter.SimpleUpdate("editReply", "replies", "content = ?, parsed_content = ?", "rid = ?")
adapter.SimpleUpdate("editProfileReply", "users_replies", "content = ?, parsed_content = ?", "rid = ?") adapter.SimpleUpdate("editProfileReply", "users_replies", "content = ?, parsed_content = ?", "rid = ?")
@ -367,7 +367,7 @@ func writeUpdates(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeDeletes(adapter qgen.DB_Adapter) error { func writeDeletes(adapter qgen.Adapter) error {
adapter.SimpleDelete("deleteProfileReply", "users_replies", "rid = ?") adapter.SimpleDelete("deleteProfileReply", "users_replies", "rid = ?")
//adapter.SimpleDelete("deleteForumPermsByForum", "forums_permissions", "fid = ?") //adapter.SimpleDelete("deleteForumPermsByForum", "forums_permissions", "fid = ?")
@ -380,7 +380,7 @@ func writeDeletes(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeSimpleCounts(adapter qgen.DB_Adapter) error { func writeSimpleCounts(adapter qgen.Adapter) error {
adapter.SimpleCount("reportExists", "topics", "data = ? AND data != '' AND parentID = 1", "") adapter.SimpleCount("reportExists", "topics", "data = ? AND data != '' AND parentID = 1", "")
adapter.SimpleCount("modlogCount", "moderation_logs", "", "") adapter.SimpleCount("modlogCount", "moderation_logs", "", "")
@ -388,7 +388,7 @@ func writeSimpleCounts(adapter qgen.DB_Adapter) error {
return nil return nil
} }
func writeInsertSelects(adapter qgen.DB_Adapter) error { func writeInsertSelects(adapter qgen.Adapter) error {
/*adapter.SimpleInsertSelect("addForumPermsToForumAdmins", /*adapter.SimpleInsertSelect("addForumPermsToForumAdmins",
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""}, qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""},
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""}, qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""},
@ -408,14 +408,14 @@ func writeInsertSelects(adapter qgen.DB_Adapter) error {
} }
// nolint // nolint
func writeInsertLeftJoins(adapter qgen.DB_Adapter) error { func writeInsertLeftJoins(adapter qgen.Adapter) error {
return nil return nil
} }
func writeInsertInnerJoins(adapter qgen.DB_Adapter) error { func writeInsertInnerJoins(adapter qgen.Adapter) error {
adapter.SimpleInsertInnerJoin("notifyWatchers", adapter.SimpleInsertInnerJoin("notifyWatchers",
qgen.DB_Insert{"activity_stream_matches", "watcher, asid", ""}, qgen.DBInsert{"activity_stream_matches", "watcher, asid", ""},
qgen.DB_Join{"activity_stream", "activity_subscriptions", "activity_subscriptions.user, activity_stream.asid", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", ""}, qgen.DBJoin{"activity_stream", "activity_subscriptions", "activity_subscriptions.user, activity_stream.asid", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", ""},
) )
return nil return nil

View File

@ -14,7 +14,7 @@ func NewPrimaryKeySpitter() *PrimaryKeySpitter {
func (spit *PrimaryKeySpitter) Hook(name string, args ...interface{}) error { func (spit *PrimaryKeySpitter) Hook(name string, args ...interface{}) error {
if name == "CreateTableStart" { if name == "CreateTableStart" {
var found string var found string
for _, key := range args[4].([]qgen.DB_Table_Key) { for _, key := range args[4].([]qgen.DBTableKey) {
if key.Type == "primary" { if key.Type == "primary" {
expl := strings.Split(key.Columns, ",") expl := strings.Split(key.Columns, ",")
if len(expl) > 1 { if len(expl) > 1 {

View File

@ -3,53 +3,55 @@ package main
import "./lib" import "./lib"
func createTables(adapter qgen.DB_Adapter) error { func createTables(adapter qgen.Adapter) error {
qgen.Install.CreateTable("users", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("users", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"uid", "int", 0, false, true, ""}, qgen.DBTableColumn{"uid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"name", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"password", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"password", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"salt", "varchar", 80, false, false, "''"},
qgen.DB_Table_Column{"group", "int", 0, false, false, ""}, qgen.DBTableColumn{"salt", "varchar", 80, false, false, "''"},
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"group", "int", 0, false, false, ""},
qgen.DB_Table_Column{"is_super_admin", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"active", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"is_super_admin", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"lastActiveAt", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""},
qgen.DB_Table_Column{"session", "varchar", 200, false, false, "''"}, qgen.DBTableColumn{"lastActiveAt", "datetime", 0, false, false, ""},
qgen.DB_Table_Column{"last_ip", "varchar", 200, false, false, "0.0.0.0.0"}, qgen.DBTableColumn{"session", "varchar", 200, false, false, "''"},
qgen.DB_Table_Column{"email", "varchar", 200, false, false, "''"}, qgen.DBTableColumn{"last_ip", "varchar", 200, false, false, "0.0.0.0.0"},
qgen.DB_Table_Column{"avatar", "varchar", 100, false, false, "''"}, qgen.DBTableColumn{"email", "varchar", 200, false, false, "''"},
qgen.DB_Table_Column{"message", "text", 0, false, false, "''"}, qgen.DBTableColumn{"avatar", "varchar", 100, false, false, "''"},
qgen.DB_Table_Column{"url_prefix", "varchar", 20, false, false, "''"}, qgen.DBTableColumn{"message", "text", 0, false, false, "''"},
qgen.DB_Table_Column{"url_name", "varchar", 100, false, false, "''"}, qgen.DBTableColumn{"url_prefix", "varchar", 20, false, false, "''"},
qgen.DB_Table_Column{"level", "smallint", 0, false, false, "0"}, qgen.DBTableColumn{"url_name", "varchar", 100, false, false, "''"},
qgen.DB_Table_Column{"score", "int", 0, false, false, "0"}, qgen.DBTableColumn{"level", "smallint", 0, false, false, "0"},
qgen.DB_Table_Column{"posts", "int", 0, false, false, "0"}, qgen.DBTableColumn{"score", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"bigposts", "int", 0, false, false, "0"}, qgen.DBTableColumn{"posts", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"megaposts", "int", 0, false, false, "0"}, qgen.DBTableColumn{"bigposts", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"topics", "int", 0, false, false, "0"}, qgen.DBTableColumn{"megaposts", "int", 0, false, false, "0"},
//qgen.DB_Table_Column{"penalty_count","int",0,false,false,"0"}, qgen.DBTableColumn{"topics", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"temp_group", "int", 0, false, false, "0"}, // For temporary groups, set this to zero when a temporary group isn't in effect //qgen.DBTableColumn{"penalty_count","int",0,false,false,"0"},
qgen.DBTableColumn{"temp_group", "int", 0, false, false, "0"}, // For temporary groups, set this to zero when a temporary group isn't in effect
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"uid", "primary"}, qgen.DBTableKey{"uid", "primary"},
qgen.DB_Table_Key{"name", "unique"}, qgen.DBTableKey{"name", "unique"},
}, },
) )
qgen.Install.CreateTable("users_groups", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("users_groups", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"gid", "int", 0, false, true, ""}, qgen.DBTableColumn{"gid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"name", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"permissions", "text", 0, false, false, ""}, qgen.DBTableColumn{"permissions", "text", 0, false, false, ""},
qgen.DB_Table_Column{"plugin_perms", "text", 0, false, false, ""}, qgen.DBTableColumn{"plugin_perms", "text", 0, false, false, ""},
qgen.DB_Table_Column{"is_mod", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"is_mod", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"is_admin", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"is_admin", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"is_banned", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"is_banned", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"tag", "varchar", 50, false, false, "''"},
qgen.DBTableColumn{"tag", "varchar", 50, false, false, "''"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"gid", "primary"}, qgen.DBTableKey{"gid", "primary"},
}, },
) )
@ -60,303 +62,303 @@ func createTables(adapter qgen.DB_Adapter) error {
// TODO: Add a penalty type where a user is stopped from creating plugin_guilds social groups // TODO: Add a penalty type where a user is stopped from creating plugin_guilds social groups
// TODO: Shadow bans. We will probably have a CanShadowBan permission for this, as we *really* don't want people using this lightly. // TODO: Shadow bans. We will probably have a CanShadowBan permission for this, as we *really* don't want people using this lightly.
/*qgen.Install.CreateTable("users_penalties","","", /*qgen.Install.CreateTable("users_penalties","","",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"uid","int",0,false,false,""}, qgen.DBTableColumn{"uid","int",0,false,false,""},
qgen.DB_Table_Column{"element_id","int",0,false,false,""}, qgen.DBTableColumn{"element_id","int",0,false,false,""},
qgen.DB_Table_Column{"element_type","varchar",50,false,false,""}, //forum, profile?, and social_group. Leave blank for global. qgen.DBTableColumn{"element_type","varchar",50,false,false,""}, //forum, profile?, and social_group. Leave blank for global.
qgen.DB_Table_Column{"overrides","text",0,false,false,"{}"}, qgen.DBTableColumn{"overrides","text",0,false,false,"{}"},
qgen.DB_Table_Column{"mod_queue","boolean",0,false,false,"0"}, qgen.DBTableColumn{"mod_queue","boolean",0,false,false,"0"},
qgen.DB_Table_Column{"shadow_ban","boolean",0,false,false,"0"}, qgen.DBTableColumn{"shadow_ban","boolean",0,false,false,"0"},
qgen.DB_Table_Column{"no_avatar","boolean",0,false,false,"0"}, // Coming Soon. Should this be a perm override instead? qgen.DBTableColumn{"no_avatar","boolean",0,false,false,"0"}, // Coming Soon. Should this be a perm override instead?
// Do we *really* need rate-limit penalty types? Are we going to be allowing bots or something? // Do we *really* need rate-limit penalty types? Are we going to be allowing bots or something?
//qgen.DB_Table_Column{"posts_per_hour","int",0,false,false,"0"}, //qgen.DBTableColumn{"posts_per_hour","int",0,false,false,"0"},
//qgen.DB_Table_Column{"topics_per_hour","int",0,false,false,"0"}, //qgen.DBTableColumn{"topics_per_hour","int",0,false,false,"0"},
//qgen.DB_Table_Column{"posts_count","int",0,false,false,"0"}, //qgen.DBTableColumn{"posts_count","int",0,false,false,"0"},
//qgen.DB_Table_Column{"topic_count","int",0,false,false,"0"}, //qgen.DBTableColumn{"topic_count","int",0,false,false,"0"},
//qgen.DB_Table_Column{"last_hour","int",0,false,false,"0"}, // UNIX Time, as we don't need to do anything too fancy here. When an hour has elapsed since that time, reset the hourly penalty counters. //qgen.DBTableColumn{"last_hour","int",0,false,false,"0"}, // UNIX Time, as we don't need to do anything too fancy here. When an hour has elapsed since that time, reset the hourly penalty counters.
qgen.DB_Table_Column{"issued_by","int",0,false,false,""}, qgen.DBTableColumn{"issued_by","int",0,false,false,""},
qgen.DB_Table_Column{"issued_at","createdAt",0,false,false,""}, qgen.DBTableColumn{"issued_at","createdAt",0,false,false,""},
qgen.DB_Table_Column{"expires_at","datetime",0,false,false,""}, qgen.DBTableColumn{"expires_at","datetime",0,false,false,""},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
)*/ )*/
qgen.Install.CreateTable("users_groups_scheduler", "", "", qgen.Install.CreateTable("users_groups_scheduler", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""}, qgen.DBTableColumn{"uid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"set_group", "int", 0, false, false, ""}, qgen.DBTableColumn{"set_group", "int", 0, false, false, ""},
qgen.DB_Table_Column{"issued_by", "int", 0, false, false, ""}, qgen.DBTableColumn{"issued_by", "int", 0, false, false, ""},
qgen.DB_Table_Column{"issued_at", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"issued_at", "createdAt", 0, false, false, ""},
qgen.DB_Table_Column{"revert_at", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"revert_at", "datetime", 0, false, false, ""},
qgen.DB_Table_Column{"temporary", "boolean", 0, false, false, ""}, // special case for permanent bans to do the necessary bookkeeping, might be removed in the future qgen.DBTableColumn{"temporary", "boolean", 0, false, false, ""}, // special case for permanent bans to do the necessary bookkeeping, might be removed in the future
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"uid", "primary"}, qgen.DBTableKey{"uid", "primary"},
}, },
) )
qgen.Install.CreateTable("emails", "", "", qgen.Install.CreateTable("emails", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"email", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"email", "varchar", 200, false, false, ""},
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""}, qgen.DBTableColumn{"uid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"validated", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"validated", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"token", "varchar", 200, false, false, "''"}, qgen.DBTableColumn{"token", "varchar", 200, false, false, "''"},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("forums", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("forums", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"fid", "int", 0, false, true, ""}, qgen.DBTableColumn{"fid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"name", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"desc", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"desc", "varchar", 200, false, false, ""},
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "1"}, qgen.DBTableColumn{"active", "boolean", 0, false, false, "1"},
qgen.DB_Table_Column{"topicCount", "int", 0, false, false, "0"}, qgen.DBTableColumn{"topicCount", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"preset", "varchar", 100, false, false, "''"}, qgen.DBTableColumn{"preset", "varchar", 100, false, false, "''"},
qgen.DB_Table_Column{"parentID", "int", 0, false, false, "0"}, qgen.DBTableColumn{"parentID", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"parentType", "varchar", 50, false, false, "''"}, qgen.DBTableColumn{"parentType", "varchar", 50, false, false, "''"},
qgen.DB_Table_Column{"lastTopicID", "int", 0, false, false, "0"}, qgen.DBTableColumn{"lastTopicID", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"lastReplyerID", "int", 0, false, false, "0"}, qgen.DBTableColumn{"lastReplyerID", "int", 0, false, false, "0"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"fid", "primary"}, qgen.DBTableKey{"fid", "primary"},
}, },
) )
qgen.Install.CreateTable("forums_permissions", "", "", qgen.Install.CreateTable("forums_permissions", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"fid", "int", 0, false, false, ""}, qgen.DBTableColumn{"fid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"gid", "int", 0, false, false, ""}, qgen.DBTableColumn{"gid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"preset", "varchar", 100, false, false, "''"}, qgen.DBTableColumn{"preset", "varchar", 100, false, false, "''"},
qgen.DB_Table_Column{"permissions", "text", 0, false, false, ""}, qgen.DBTableColumn{"permissions", "text", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
// TODO: Test to see that the compound primary key works // TODO: Test to see that the compound primary key works
qgen.DB_Table_Key{"fid,gid", "primary"}, qgen.DBTableKey{"fid,gid", "primary"},
}, },
) )
qgen.Install.CreateTable("topics", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("topics", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"tid", "int", 0, false, true, ""}, qgen.DBTableColumn{"tid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"title", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"title", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"content", "text", 0, false, false, ""}, qgen.DBTableColumn{"content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""}, qgen.DBTableColumn{"parsed_content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""},
qgen.DB_Table_Column{"lastReplyAt", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"lastReplyAt", "datetime", 0, false, false, ""},
qgen.DB_Table_Column{"lastReplyBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"lastReplyBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"createdBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"is_closed", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"is_closed", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"sticky", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"sticky", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"parentID", "int", 0, false, false, "2"}, qgen.DBTableColumn{"parentID", "int", 0, false, false, "2"},
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"}, qgen.DBTableColumn{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
qgen.DB_Table_Column{"postCount", "int", 0, false, false, "1"}, qgen.DBTableColumn{"postCount", "int", 0, false, false, "1"},
qgen.DB_Table_Column{"likeCount", "int", 0, false, false, "0"}, qgen.DBTableColumn{"likeCount", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"words", "int", 0, false, false, "0"}, qgen.DBTableColumn{"words", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"css_class", "varchar", 100, false, false, "''"}, qgen.DBTableColumn{"css_class", "varchar", 100, false, false, "''"},
qgen.DB_Table_Column{"data", "varchar", 200, false, false, "''"}, qgen.DBTableColumn{"data", "varchar", 200, false, false, "''"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"tid", "primary"}, qgen.DBTableKey{"tid", "primary"},
}, },
) )
qgen.Install.CreateTable("replies", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("replies", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"rid", "int", 0, false, true, ""}, qgen.DBTableColumn{"rid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"tid", "int", 0, false, false, ""}, qgen.DBTableColumn{"tid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"content", "text", 0, false, false, ""}, qgen.DBTableColumn{"content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""}, qgen.DBTableColumn{"parsed_content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""},
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"createdBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"lastEdit", "int", 0, false, false, "0"}, qgen.DBTableColumn{"lastEdit", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"lastEditBy", "int", 0, false, false, "0"}, qgen.DBTableColumn{"lastEditBy", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"lastUpdated", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"lastUpdated", "datetime", 0, false, false, ""},
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"}, qgen.DBTableColumn{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
qgen.DB_Table_Column{"likeCount", "int", 0, false, false, "0"}, qgen.DBTableColumn{"likeCount", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"words", "int", 0, false, false, "1"}, // ? - replies has a default of 1 and topics has 0? why? qgen.DBTableColumn{"words", "int", 0, false, false, "1"}, // ? - replies has a default of 1 and topics has 0? why?
qgen.DB_Table_Column{"actionType", "varchar", 20, false, false, "''"}, qgen.DBTableColumn{"actionType", "varchar", 20, false, false, "''"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"rid", "primary"}, qgen.DBTableKey{"rid", "primary"},
}, },
) )
qgen.Install.CreateTable("attachments", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("attachments", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"attachID", "int", 0, false, true, ""}, qgen.DBTableColumn{"attachID", "int", 0, false, true, ""},
qgen.DB_Table_Column{"sectionID", "int", 0, false, false, "0"}, qgen.DBTableColumn{"sectionID", "int", 0, false, false, "0"},
qgen.DB_Table_Column{"sectionTable", "varchar", 200, false, false, "forums"}, qgen.DBTableColumn{"sectionTable", "varchar", 200, false, false, "forums"},
qgen.DB_Table_Column{"originID", "int", 0, false, false, ""}, qgen.DBTableColumn{"originID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"originTable", "varchar", 200, false, false, "replies"}, qgen.DBTableColumn{"originTable", "varchar", 200, false, false, "replies"},
qgen.DB_Table_Column{"uploadedBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"uploadedBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"path", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"path", "varchar", 200, false, false, ""},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"attachID", "primary"}, qgen.DBTableKey{"attachID", "primary"},
}, },
) )
qgen.Install.CreateTable("revisions", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("revisions", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"index", "int", 0, false, false, ""}, // TODO: Replace this with a proper revision ID x.x qgen.DBTableColumn{"index", "int", 0, false, false, ""}, // TODO: Replace this with a proper revision ID x.x
qgen.DB_Table_Column{"content", "text", 0, false, false, ""}, qgen.DBTableColumn{"content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"contentID", "int", 0, false, false, ""}, qgen.DBTableColumn{"contentID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"contentType", "varchar", 100, false, false, "replies"}, qgen.DBTableColumn{"contentType", "varchar", 100, false, false, "replies"},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("users_replies", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("users_replies", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"rid", "int", 0, false, true, ""}, qgen.DBTableColumn{"rid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""}, qgen.DBTableColumn{"uid", "int", 0, false, false, ""},
qgen.DB_Table_Column{"content", "text", 0, false, false, ""}, qgen.DBTableColumn{"content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""}, qgen.DBTableColumn{"parsed_content", "text", 0, false, false, ""},
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""},
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"createdBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"lastEdit", "int", 0, false, false, ""}, qgen.DBTableColumn{"lastEdit", "int", 0, false, false, ""},
qgen.DB_Table_Column{"lastEditBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"lastEditBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"}, qgen.DBTableColumn{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"rid", "primary"}, qgen.DBTableKey{"rid", "primary"},
}, },
) )
qgen.Install.CreateTable("likes", "", "", qgen.Install.CreateTable("likes", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"weight", "tinyint", 0, false, false, "1"}, qgen.DBTableColumn{"weight", "tinyint", 0, false, false, "1"},
qgen.DB_Table_Column{"targetItem", "int", 0, false, false, ""}, qgen.DBTableColumn{"targetItem", "int", 0, false, false, ""},
qgen.DB_Table_Column{"targetType", "varchar", 50, false, false, "replies"}, qgen.DBTableColumn{"targetType", "varchar", 50, false, false, "replies"},
qgen.DB_Table_Column{"sentBy", "int", 0, false, false, ""}, qgen.DBTableColumn{"sentBy", "int", 0, false, false, ""},
qgen.DB_Table_Column{"recalc", "tinyint", 0, false, false, "0"}, qgen.DBTableColumn{"recalc", "tinyint", 0, false, false, "0"},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("activity_stream_matches", "", "", qgen.Install.CreateTable("activity_stream_matches", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"watcher", "int", 0, false, false, ""}, qgen.DBTableColumn{"watcher", "int", 0, false, false, ""},
qgen.DB_Table_Column{"asid", "int", 0, false, false, ""}, qgen.DBTableColumn{"asid", "int", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("activity_stream", "", "", qgen.Install.CreateTable("activity_stream", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"asid", "int", 0, false, true, ""}, qgen.DBTableColumn{"asid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"actor", "int", 0, false, false, ""}, /* the one doing the act */ qgen.DBTableColumn{"actor", "int", 0, false, false, ""}, /* the one doing the act */
qgen.DB_Table_Column{"targetUser", "int", 0, false, false, ""}, /* the user who created the item the actor is acting on, some items like forums may lack a targetUser field */ qgen.DBTableColumn{"targetUser", "int", 0, false, false, ""}, /* the user who created the item the actor is acting on, some items like forums may lack a targetUser field */
qgen.DB_Table_Column{"event", "varchar", 50, false, false, ""}, /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */ qgen.DBTableColumn{"event", "varchar", 50, false, false, ""}, /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */
qgen.DB_Table_Column{"elementType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */ qgen.DBTableColumn{"elementType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */ qgen.DBTableColumn{"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"asid", "primary"}, qgen.DBTableKey{"asid", "primary"},
}, },
) )
qgen.Install.CreateTable("activity_subscriptions", "", "", qgen.Install.CreateTable("activity_subscriptions", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"user", "int", 0, false, false, ""}, qgen.DBTableColumn{"user", "int", 0, false, false, ""},
qgen.DB_Table_Column{"targetID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */ qgen.DBTableColumn{"targetID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
qgen.DB_Table_Column{"targetType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */ qgen.DBTableColumn{"targetType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
qgen.DB_Table_Column{"level", "int", 0, false, false, "0"}, /* 0: Mentions (aka the global default for any post), 1: Replies To You, 2: All Replies*/ qgen.DBTableColumn{"level", "int", 0, false, false, "0"}, /* 0: Mentions (aka the global default for any post), 1: Replies To You, 2: All Replies*/
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
/* Due to MySQL's design, we have to drop the unique keys for table settings, plugins, and themes down from 200 to 180 or it will error */ /* Due to MySQL's design, we have to drop the unique keys for table settings, plugins, and themes down from 200 to 180 or it will error */
qgen.Install.CreateTable("settings", "", "", qgen.Install.CreateTable("settings", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"name", "varchar", 180, false, false, ""}, qgen.DBTableColumn{"name", "varchar", 180, false, false, ""},
qgen.DB_Table_Column{"content", "varchar", 250, false, false, ""}, qgen.DBTableColumn{"content", "varchar", 250, false, false, ""},
qgen.DB_Table_Column{"type", "varchar", 50, false, false, ""}, qgen.DBTableColumn{"type", "varchar", 50, false, false, ""},
qgen.DB_Table_Column{"constraints", "varchar", 200, false, false, "''"}, qgen.DBTableColumn{"constraints", "varchar", 200, false, false, "''"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"name", "unique"}, qgen.DBTableKey{"name", "unique"},
}, },
) )
qgen.Install.CreateTable("word_filters", "", "", qgen.Install.CreateTable("word_filters", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"wfid", "int", 0, false, true, ""}, qgen.DBTableColumn{"wfid", "int", 0, false, true, ""},
qgen.DB_Table_Column{"find", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"find", "varchar", 200, false, false, ""},
qgen.DB_Table_Column{"replacement", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"replacement", "varchar", 200, false, false, ""},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"wfid", "primary"}, qgen.DBTableKey{"wfid", "primary"},
}, },
) )
qgen.Install.CreateTable("plugins", "", "", qgen.Install.CreateTable("plugins", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"uname", "varchar", 180, false, false, ""}, qgen.DBTableColumn{"uname", "varchar", 180, false, false, ""},
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"active", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"installed", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"installed", "boolean", 0, false, false, "0"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"uname", "unique"}, qgen.DBTableKey{"uname", "unique"},
}, },
) )
qgen.Install.CreateTable("themes", "", "", qgen.Install.CreateTable("themes", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"uname", "varchar", 180, false, false, ""}, qgen.DBTableColumn{"uname", "varchar", 180, false, false, ""},
qgen.DB_Table_Column{"default", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"default", "boolean", 0, false, false, "0"},
}, },
[]qgen.DB_Table_Key{ []qgen.DBTableKey{
qgen.DB_Table_Key{"uname", "unique"}, qgen.DBTableKey{"uname", "unique"},
}, },
) )
qgen.Install.CreateTable("widgets", "", "", qgen.Install.CreateTable("widgets", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"position", "int", 0, false, false, ""}, qgen.DBTableColumn{"position", "int", 0, false, false, ""},
qgen.DB_Table_Column{"side", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"side", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"type", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"type", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"}, qgen.DBTableColumn{"active", "boolean", 0, false, false, "0"},
qgen.DB_Table_Column{"location", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"location", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"data", "text", 0, false, false, "''"}, qgen.DBTableColumn{"data", "text", 0, false, false, "''"},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("moderation_logs", "", "", qgen.Install.CreateTable("moderation_logs", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"action", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"action", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""}, qgen.DBTableColumn{"elementID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"elementType", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"elementType", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"ipaddress", "varchar", 200, false, false, ""},
qgen.DB_Table_Column{"actorID", "int", 0, false, false, ""}, qgen.DBTableColumn{"actorID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"doneAt", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"doneAt", "datetime", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("administration_logs", "", "", qgen.Install.CreateTable("administration_logs", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"action", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"action", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""}, qgen.DBTableColumn{"elementID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"elementType", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"elementType", "varchar", 100, false, false, ""},
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, ""}, qgen.DBTableColumn{"ipaddress", "varchar", 200, false, false, ""},
qgen.DB_Table_Column{"actorID", "int", 0, false, false, ""}, qgen.DBTableColumn{"actorID", "int", 0, false, false, ""},
qgen.DB_Table_Column{"doneAt", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"doneAt", "datetime", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
qgen.Install.CreateTable("sync", "", "", qgen.Install.CreateTable("sync", "", "",
[]qgen.DB_Table_Column{ []qgen.DBTableColumn{
qgen.DB_Table_Column{"last_update", "datetime", 0, false, false, ""}, qgen.DBTableColumn{"last_update", "datetime", 0, false, false, ""},
}, },
[]qgen.DB_Table_Key{}, []qgen.DBTableKey{},
) )
return nil return nil