The Advanced Forum Editor is now accessible via the Forum Manager.

Renamed data.sql to mysql.sql
Added a composite primary key to the forums_permissions table.
Moved five more queries to the query generator.
Revamped the query generator. Yesterday's commit was more of a prototype. Still lots to be done to facilitate all the queries.
Added support for simple left joins to the query generator.
Removed .smaller
Fixed an issue with the permissions not saving with the Advanced Forum Editor.

Remind me to keep all generators away from Atom.
This commit is contained in:
Azareal 2017-06-06 09:47:33 +01:00
parent e099dfd40e
commit 93d00b0337
11 changed files with 251 additions and 131 deletions

View File

@ -11,6 +11,11 @@ var get_reply_stmt *sql.Stmt
var login_stmt *sql.Stmt var login_stmt *sql.Stmt
var get_password_stmt *sql.Stmt var get_password_stmt *sql.Stmt
var username_exists_stmt *sql.Stmt var username_exists_stmt *sql.Stmt
var get_settings_stmt *sql.Stmt
var get_setting_stmt *sql.Stmt
var get_full_setting_stmt *sql.Stmt
var is_plugin_active_stmt *sql.Stmt
var get_topic_list_stmt *sql.Stmt
func gen_mysql() (err error) { func gen_mysql() (err error) {
if debug { if debug {
@ -18,43 +23,73 @@ func gen_mysql() (err error) {
} }
log.Print("Preparing get_user statement.") log.Print("Preparing get_user statement.")
get_user_stmt, err = db.Prepare("SELECT `name`,`group`,`is_super_admin`,`avatar`,`message`,`url_prefix`,`url_name`,`level` FROM users WHERE `uid`= ?") get_user_stmt, err = db.Prepare("SELECT `name`,`group`,`is_super_admin`,`avatar`,`message`,`url_prefix`,`url_name`,`level` FROM users WHERE `uid` = ?")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing get_full_user statement.") log.Print("Preparing get_full_user statement.")
get_full_user_stmt, err = db.Prepare("SELECT `name`,`group`,`is_super_admin`,`session`,`email`,`avatar`,`message`,`url_prefix`,`url_name`,`level`,`score`,`last_ip` FROM users WHERE `uid`= ?") get_full_user_stmt, err = db.Prepare("SELECT `name`,`group`,`is_super_admin`,`session`,`email`,`avatar`,`message`,`url_prefix`,`url_name`,`level`,`score`,`last_ip` FROM users WHERE `uid` = ?")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing get_topic statement.") log.Print("Preparing get_topic statement.")
get_topic_stmt, err = db.Prepare("SELECT `title`,`content`,`createdBy`,`createdAt`,`is_closed`,`sticky`,`parentID`,`ipaddress`,`postCount`,`likeCount` FROM topics WHERE `tid`= ?") get_topic_stmt, err = db.Prepare("SELECT `title`,`content`,`createdBy`,`createdAt`,`is_closed`,`sticky`,`parentID`,`ipaddress`,`postCount`,`likeCount` FROM topics WHERE `tid` = ?")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing get_reply statement.") log.Print("Preparing get_reply statement.")
get_reply_stmt, err = db.Prepare("SELECT `content`,`createdBy`,`createdAt`,`lastEdit`,`lastEditBy`,`ipaddress`,`likeCount` FROM replies WHERE `rid`= ?") get_reply_stmt, err = db.Prepare("SELECT `content`,`createdBy`,`createdAt`,`lastEdit`,`lastEditBy`,`ipaddress`,`likeCount` FROM replies WHERE `rid` = ?")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing login statement.") log.Print("Preparing login statement.")
login_stmt, err = db.Prepare("SELECT `uid`,`name`,`password`,`salt` FROM users WHERE `name`= ?") login_stmt, err = db.Prepare("SELECT `uid`,`name`,`password`,`salt` FROM users WHERE `name` = ?")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing get_password statement.") log.Print("Preparing get_password statement.")
get_password_stmt, err = db.Prepare("SELECT `password`,`salt` FROM users WHERE `uid`= ?") get_password_stmt, err = db.Prepare("SELECT `password`,`salt` FROM users WHERE `uid` = ?")
if err != nil { if err != nil {
return err return err
} }
log.Print("Preparing username_exists statement.") log.Print("Preparing username_exists statement.")
username_exists_stmt, err = db.Prepare("SELECT `name` FROM users WHERE `name`= ?") username_exists_stmt, err = db.Prepare("SELECT `name` FROM users WHERE `name` = ?")
if err != nil {
return err
}
log.Print("Preparing get_settings statement.")
get_settings_stmt, err = db.Prepare("SELECT `name`,`content`,`type` FROM settings")
if err != nil {
return err
}
log.Print("Preparing get_setting statement.")
get_setting_stmt, err = db.Prepare("SELECT `content`,`type` FROM settings WHERE `name` = ?")
if err != nil {
return err
}
log.Print("Preparing get_full_setting statement.")
get_full_setting_stmt, err = db.Prepare("SELECT `name`,`type`,`constraints` FROM settings WHERE `name` = ?")
if err != nil {
return err
}
log.Print("Preparing is_plugin_active statement.")
is_plugin_active_stmt, err = db.Prepare("SELECT `active` FROM plugins WHERE `uname` = ?")
if err != nil {
return err
}
log.Print("Preparing get_topic_list statement.")
get_topic_list_stmt, err = db.Prepare("SELECT `topics`.`tid`,`topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`createdAt`,`topics`.`parentID`,`users`.`name`,`users`.`avatar` FROM topics LEFT JOIN users ON `topics`.`createdBy`=`users`.`uid` ORDER BY topics.sticky DESC,topics.lastReplyAt DESC,topics.createdBy DESC")
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,25 +1,22 @@
/* Copyright Azareal 2017 - 2018 */ /* Copyright Azareal 2017 - 2018 */
package main package main
import "fmt" import (
import "os" "fmt"
import "bytes" "os"
import "bufio" "bytes"
import "strconv" "bufio"
import "io/ioutil" "strconv"
import "database/sql" "io/ioutil"
import _ "github.com/go-sql-driver/mysql" "database/sql"
_ "github.com/go-sql-driver/mysql"
)
var scanner *bufio.Scanner var scanner *bufio.Scanner
var db_host string var db_host, db_username, db_password, db_name string
var db_username string
var db_password string
var db_name string
//var db_collation string = "utf8mb4_general_ci" //var db_collation string = "utf8mb4_general_ci"
var db_port string = "3306" var db_port string = "3306"
var site_name string var site_name, site_url, server_port string
var site_url string
var server_port string
var default_host string = "localhost" var default_host string = "localhost"
var default_username string = "root" var default_username string = "root"
@ -43,7 +40,7 @@ func main() {
press_any_key() press_any_key()
return return
} }
if !get_site_details() { if !get_site_details() {
err := scanner.Err() err := scanner.Err()
if err != nil { if err != nil {
@ -55,7 +52,7 @@ func main() {
press_any_key() press_any_key()
return return
} }
_db_password := db_password _db_password := db_password
if(_db_password != ""){ if(_db_password != ""){
_db_password = ":" + _db_password _db_password = ":" + _db_password
@ -67,7 +64,7 @@ func main() {
press_any_key() press_any_key()
return return
} }
// Make sure that the connection is alive.. // Make sure that the connection is alive..
err = db.Ping() err = db.Ping()
if err != nil { if err != nil {
@ -79,14 +76,14 @@ func main() {
fmt.Println("Successfully connected to the database") fmt.Println("Successfully connected to the database")
fmt.Println("Opening the database seed file") fmt.Println("Opening the database seed file")
sqlContents, err := ioutil.ReadFile("./data.sql") sqlContents, err := ioutil.ReadFile("./mysql.sql")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
fmt.Println("Aborting installation...") fmt.Println("Aborting installation...")
press_any_key() press_any_key()
return return
} }
var waste string var waste string
err = db.QueryRow("SHOW DATABASES LIKE '" + db_name + "'").Scan(&waste) err = db.QueryRow("SHOW DATABASES LIKE '" + db_name + "'").Scan(&waste)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
@ -95,7 +92,7 @@ func main() {
press_any_key() press_any_key()
return return
} }
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
fmt.Println("Unable to find the database. Attempting to create it") fmt.Println("Unable to find the database. Attempting to create it")
_,err = db.Exec("CREATE DATABASE IF NOT EXISTS " + db_name + "") _,err = db.Exec("CREATE DATABASE IF NOT EXISTS " + db_name + "")
@ -107,7 +104,7 @@ func main() {
} }
fmt.Println("The database was successfully created") fmt.Println("The database was successfully created")
} }
fmt.Println("Switching to database " + db_name) fmt.Println("Switching to database " + db_name)
_, err = db.Exec("USE " + db_name) _, err = db.Exec("USE " + db_name)
if err != nil { if err != nil {
@ -116,7 +113,7 @@ func main() {
press_any_key() press_any_key()
return return
} }
fmt.Println("Preparing installation queries") fmt.Println("Preparing installation queries")
sqlContents = bytes.TrimSpace(sqlContents) sqlContents = bytes.TrimSpace(sqlContents)
statements := bytes.Split(sqlContents, []byte(";")) statements := bytes.Split(sqlContents, []byte(";"))
@ -124,7 +121,7 @@ func main() {
if len(statement) == 0 { if len(statement) == 0 {
continue continue
} }
fmt.Println("Executing query #" + strconv.Itoa(key) + " " + string(statement)) fmt.Println("Executing query #" + strconv.Itoa(key) + " " + string(statement))
_, err = db.Exec(string(statement)) _, err = db.Exec(string(statement))
if err != nil { if err != nil {
@ -135,7 +132,7 @@ func main() {
} }
} }
fmt.Println("Finished inserting the database data") fmt.Println("Finished inserting the database data")
configContents := []byte(`package main configContents := []byte(`package main
// Site Info // Site Info
@ -186,7 +183,7 @@ var debug = true
var super_debug = false var super_debug = false
var profiling = false var profiling = false
`) `)
fmt.Println("Opening the configuration file") fmt.Println("Opening the configuration file")
configFile, err := os.Create("./config.go") configFile, err := os.Create("./config.go")
if err != nil { if err != nil {
@ -195,7 +192,7 @@ var profiling = false
press_any_key() press_any_key()
return return
} }
fmt.Println("Writing to the configuration file...") fmt.Println("Writing to the configuration file...")
_, err = configFile.Write(configContents) _, err = configFile.Write(configContents)
if err != nil { if err != nil {
@ -204,11 +201,11 @@ var profiling = false
press_any_key() press_any_key()
return return
} }
configFile.Sync() configFile.Sync()
configFile.Close() configFile.Close()
fmt.Println("Finished writing to the configuration file") fmt.Println("Finished writing to the configuration file")
fmt.Println("Yay, you have successfully installed Gosora!") fmt.Println("Yay, you have successfully installed Gosora!")
fmt.Println("Your name is Admin and you can login with the password 'password'. Don't forget to change it! Seriously. It's really insecure.") fmt.Println("Your name is Admin and you can login with the password 'password'. Don't forget to change it! Seriously. It's really insecure.")
press_any_key() press_any_key()
@ -224,7 +221,7 @@ func get_database_details() bool {
db_host = default_host db_host = default_host
} }
fmt.Println("Set database host to " + db_host) fmt.Println("Set database host to " + db_host)
fmt.Println("Database Username? Default: " + default_username) fmt.Println("Database Username? Default: " + default_username)
if !scanner.Scan() { if !scanner.Scan() {
return false return false
@ -234,7 +231,7 @@ func get_database_details() bool {
db_username = default_username db_username = default_username
} }
fmt.Println("Set database username to " + db_username) fmt.Println("Set database username to " + db_username)
fmt.Println("Database Password? Default: ''") fmt.Println("Database Password? Default: ''")
if !scanner.Scan() { if !scanner.Scan() {
return false return false
@ -245,7 +242,7 @@ func get_database_details() bool {
} else { } else {
fmt.Println("Set password to " + obfuscate_password(db_password)) fmt.Println("Set password to " + obfuscate_password(db_password))
} }
fmt.Println("Database Name? Pick a name you like or one provided to you. Default: " + default_dbname) fmt.Println("Database Name? Pick a name you like or one provided to you. Default: " + default_dbname)
if !scanner.Scan() { if !scanner.Scan() {
return false return false
@ -269,7 +266,7 @@ func get_site_details() bool {
site_name = default_site_name site_name = default_site_name
} }
fmt.Println("Set the site name to " + site_name) fmt.Println("Set the site name to " + site_name)
fmt.Println("What's your site's url? Default: " + default_site_url) fmt.Println("What's your site's url? Default: " + default_site_url)
if !scanner.Scan() { if !scanner.Scan() {
return false return false
@ -279,7 +276,7 @@ func get_site_details() bool {
site_url = default_site_url site_url = default_site_url
} }
fmt.Println("Set the site url to " + site_url) fmt.Println("Set the site url to " + site_url)
fmt.Println("What port do you want the server to listen on? If you don't know what this means, you should probably leave it on the default. Default: " + default_server_port) fmt.Println("What port do you want the server to listen on? If you don't know what this means, you should probably leave it on the default. Default: " + default_server_port)
if !scanner.Scan() { if !scanner.Scan() {
return false return false
@ -311,4 +308,4 @@ func press_any_key() {
_ = scanner.Text() _ = scanner.Text()
return return
} }
} }

View File

@ -12,7 +12,6 @@ var db *sql.DB
var db_version string var db_version string
var db_collation string = "utf8mb4_general_ci" var db_collation string = "utf8mb4_general_ci"
var get_topic_list_stmt *sql.Stmt
var get_topic_user_stmt *sql.Stmt var get_topic_user_stmt *sql.Stmt
var get_topic_by_reply_stmt *sql.Stmt var get_topic_by_reply_stmt *sql.Stmt
var get_topic_replies_stmt *sql.Stmt var get_topic_replies_stmt *sql.Stmt
@ -119,12 +118,6 @@ func init_database() (err error) {
return err return err
} }
log.Print("Preparing get_topic_list statement.")
get_topic_list_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
if err != nil {
return err
}
log.Print("Preparing get_topic_user statement.") log.Print("Preparing get_topic_user statement.")
get_topic_user_stmt, err = db.Prepare("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?") get_topic_user_stmt, err = db.Prepare("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?")
if err != nil { if err != nil {

View File

@ -62,7 +62,8 @@ CREATE TABLE `forums_permissions`(
`fid` int not null, `fid` int not null,
`gid` int not null, `gid` int not null,
`preset` varchar(100) DEFAULT '' not null, `preset` varchar(100) DEFAULT '' not null,
`permissions` text not null `permissions` text not null,
primary key(fid, gid)
); );
CREATE TABLE `topics`( CREATE TABLE `topics`(

View File

@ -471,7 +471,7 @@ func route_panel_forums_edit_perms_submit(w http.ResponseWriter, r *http.Request
return return
} }
gid, err := strconv.Atoi("gid") gid, err := strconv.Atoi(r.PostFormValue("gid"))
if err != nil { if err != nil {
LocalErrorJSQ("Invalid Group ID",w,r,user,is_js) LocalErrorJSQ("Invalid Group ID",w,r,user,is_js)
return return
@ -496,6 +496,13 @@ func route_panel_forums_edit_perms_submit(w http.ResponseWriter, r *http.Request
return return
} }
permupdate_mutex.Unlock() permupdate_mutex.Unlock()
_, err = update_forum_stmt.Exec(forums[fid].Name,forums[fid].Desc,forums[fid].Active,"",fid)
if err != nil {
InternalErrorJSQ(err,w,r,is_js)
return
}
forums[fid].Preset = ""
} }
if is_js == "0" { if is_js == "0" {
@ -516,7 +523,7 @@ func route_panel_settings(w http.ResponseWriter, r *http.Request){
} }
var settingList map[string]interface{} = make(map[string]interface{}) var settingList map[string]interface{} = make(map[string]interface{})
rows, err := db.Query("select name, content, type from settings") rows, err := get_settings_stmt.Query()
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -570,7 +577,7 @@ func route_panel_setting(w http.ResponseWriter, r *http.Request, sname string){
} }
setting := Setting{sname,"","",""} setting := Setting{sname,"","",""}
err := db.QueryRow("select content, type from settings where name = ?", setting.Name).Scan(&setting.Content,&setting.Type) err := get_setting_stmt.QueryRow(setting.Name).Scan(&setting.Content,&setting.Type)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
LocalError("The setting you want to edit doesn't exist.",w,r,user) LocalError("The setting you want to edit doesn't exist.",w,r,user)
return return
@ -627,11 +634,10 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request, sname stri
return return
} }
var stype string var stype, sconstraints string
var sconstraints string
scontent := r.PostFormValue("setting-value") scontent := r.PostFormValue("setting-value")
err = db.QueryRow("select name, type, constraints from settings where name = ?", sname).Scan(&sname, &stype, &sconstraints) err = get_full_setting_stmt.QueryRow(sname).Scan(&sname, &stype, &sconstraints)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
LocalError("The setting you want to edit doesn't exist.",w,r,user) LocalError("The setting you want to edit doesn't exist.",w,r,user)
return return
@ -702,7 +708,7 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request, uname
} }
var active bool var active bool
err := db.QueryRow("select active from plugins where uname = ?", uname).Scan(&active) err := is_plugin_active_stmt.QueryRow(uname).Scan(&active)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return

View File

@ -36,16 +36,12 @@ function load_alerts(menu_alerts)
} }
} }
if(mmsg.length > 46) mmsg = mmsg.substring(0,43) + "...";
else if(mmsg.length > 35) size_dial = " smaller"; //9px
else size_dial = ""; // 10px
if("avatar" in msg) if("avatar" in msg)
{ {
alist += "<div class='alertItem withAvatar' style='background-image:url(\""+msg.avatar+"\");'><a class='text"+size_dial+"' href=\""+msg.path+"\">"+mmsg+"</a></div>"; alist += "<div class='alertItem withAvatar' style='background-image:url(\""+msg.avatar+"\");'><a class='text' href=\""+msg.path+"\">"+mmsg+"</a></div>";
anyAvatar = true anyAvatar = true
} }
else alist += "<div class='alertItem'><a href=\""+msg.path+"\" class='text"+size_dial+"'>"+mmsg+"</a></div>"; else alist += "<div class='alertItem'><a href=\""+msg.path+"\" class='text'>"+mmsg+"</a></div>";
//console.log(msg); //console.log(msg);
//console.log(mmsg); //console.log(mmsg);
} }
@ -219,6 +215,7 @@ $(document).ready(function(){
var block_parent = $(this).closest('.editable_parent'); var block_parent = $(this).closest('.editable_parent');
//console.log(block_parent); //console.log(block_parent);
block_parent.find('.hide_on_edit').hide(); block_parent.find('.hide_on_edit').hide();
block_parent.find('.show_on_edit').show();
block_parent.find('.editable_block').show(); block_parent.find('.editable_block').show();
block_parent.find('.editable_block').each(function(){ block_parent.find('.editable_block').each(function(){
var field_name = this.getAttribute("data-field"); var field_name = this.getAttribute("data-field");
@ -246,7 +243,6 @@ $(document).ready(function(){
else if(field_type=="hidden") {} else if(field_type=="hidden") {}
else this.innerHTML = "<input name='"+field_name+"' value='"+this.textContent+"' type='text'/>"; else this.innerHTML = "<input name='"+field_name+"' value='"+this.textContent+"' type='text'/>";
}); });
block_parent.find('.show_on_edit').eq(0).show();
// Remove any handlers already attached to the submitter // Remove any handlers already attached to the submitter
$(".submit_edit").unbind("click"); $(".submit_edit").unbind("click");

View File

@ -1,7 +1,7 @@
/* WIP Under Construction */ /* WIP Under Construction */
package main package main
import "fmt" //import "fmt"
import "strings" import "strings"
import "log" import "log"
import "os" import "os"
@ -9,6 +9,14 @@ import "os"
var db_registry []DB_Adapter var db_registry []DB_Adapter
var blank_order []DB_Order var blank_order []DB_Order
type DB_Column struct
{
Table string
Left string // Could be a function or a column, so I'm naming this Left
Alias string // aka AS Blah, if it's present
Type string // function or column
}
type DB_Where struct type DB_Where struct
{ {
Left string Left string
@ -20,8 +28,10 @@ type DB_Where struct
type DB_Joiner struct type DB_Joiner struct
{ {
Left string LeftTable string
Right string LeftColumn string
RightTable string
RightColumn string
} }
type DB_Order struct type DB_Order struct
@ -35,8 +45,8 @@ type DB_Adapter interface {
simple_insert(string,string,string,[]string,[]bool) error simple_insert(string,string,string,[]string,[]bool) error
//simple_replace(string,string,[]string,[]string,[]bool) error //simple_replace(string,string,[]string,[]string,[]bool) error
simple_update() error simple_update() error
simple_select(string,string,string,string,[]DB_Order/*,int,int*/) error simple_select(string,string,string,string,string/*,int,int*/) error
simple_left_join(string,string,string,string,[]DB_Joiner,string,[]DB_Order/*,int,int*/) error simple_left_join(string,string,string,string,string,string,string/*,int,int*/) error
write() error write() error
// TO-DO: Add a simple query builder // TO-DO: Add a simple query builder
} }
@ -52,46 +62,108 @@ func main() {
func write_statements(adapter DB_Adapter) error { func write_statements(adapter DB_Adapter) error {
// url_prefix and url_name will be removed from this query in a later commit // url_prefix and url_name will be removed from this query in a later commit
adapter.simple_select("get_user","users","name, group, is_super_admin, avatar, message, url_prefix, url_name, level","uid = ?",blank_order) adapter.simple_select("get_user","users","name, group, is_super_admin, avatar, message, url_prefix, url_name, level","uid = ?","")
adapter.simple_select("get_full_user","users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?",blank_order) adapter.simple_select("get_full_user","users","name, group, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, last_ip","uid = ?","")
adapter.simple_select("get_topic","topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount","tid = ?",blank_order) adapter.simple_select("get_topic","topics","title, content, createdBy, createdAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount","tid = ?","")
adapter.simple_select("get_reply","replies","content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount","rid = ?",blank_order) adapter.simple_select("get_reply","replies","content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount","rid = ?","")
adapter.simple_select("login","users","uid, name, password, salt","name = ?",blank_order) adapter.simple_select("login","users","uid, name, password, salt","name = ?","")
adapter.simple_select("get_password","users","password,salt","uid = ?",blank_order) adapter.simple_select("get_password","users","password,salt","uid = ?","")
adapter.simple_select("username_exists","users","name","name = ?",blank_order) adapter.simple_select("username_exists","users","name","name = ?","")
adapter.simple_select("get_settings","settings","name, content, type","","")
adapter.simple_select("get_setting","settings","content, type","name = ?","")
adapter.simple_select("get_full_setting","settings","name, type, constraints","name = ?","")
adapter.simple_select("is_plugin_active","plugins","active","uname = ?","")
adapter.simple_left_join("get_topic_list","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")
/*
get_topic_list_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
// A visual reference for me to glance at while I design this thing
*/
//func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table2 string, columns string, joiners []DB_Joiner, where []DB_Where, orderby []DB_Order/*, offset int, maxCount int*/) error {
/*adapter.simple_left_join("get_topic_list","topics","users",
"topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar",
[]DB_Joiner{}
)*/
return nil return nil
} }
func write_file(name string, content string) (err error) { func _process_columns(colstr string) (columns []DB_Column) {
f, err := os.Create(name) if colstr == "" {
if err != nil { return columns
return err
} }
_, err = f.WriteString(content) colstr = strings.Replace(colstr," as "," AS ",-1)
if err != nil { for _, segment := range strings.Split(colstr,",") {
return err var outcol DB_Column
dothalves := strings.Split(strings.TrimSpace(segment),".")
var halves []string
if len(dothalves) == 2 {
outcol.Table = dothalves[0]
halves = strings.Split(dothalves[1]," AS ")
} else {
halves = strings.Split(dothalves[0]," AS ")
}
halves[0] = strings.TrimSpace(halves[0])
if len(halves) == 2 {
outcol.Alias = strings.TrimSpace(halves[1])
}
if halves[0][len(halves[0]) - 1] == ')' {
outcol.Type = "function"
} else {
outcol.Type = "column"
}
outcol.Left = halves[0]
columns = append(columns,outcol)
} }
f.Sync() return columns
f.Close() }
return
func _process_orderby(orderstr string) (order []DB_Order) {
if orderstr == "" {
return order
}
for _, segment := range strings.Split(orderstr,",") {
var outorder DB_Order
halves := strings.Split(strings.TrimSpace(segment)," ")
if len(halves) != 2 {
continue
}
outorder.Column = halves[0]
outorder.Order = strings.ToLower(halves[1])
order = append(order,outorder)
}
return order
}
func _process_joiner(joinstr string) (joiner []DB_Joiner) {
if joinstr == "" {
return joiner
}
joinstr = strings.Replace(joinstr," on "," ON ",-1)
joinstr = strings.Replace(joinstr," and "," AND ",-1)
for _, segment := range strings.Split(joinstr," AND ") {
var outjoin DB_Joiner
halves := strings.Split(segment,"=")
if len(halves) != 2 {
continue
}
left_column := strings.Split(halves[0],".")
right_column := strings.Split(halves[1],".")
outjoin.LeftTable = strings.TrimSpace(left_column[0])
outjoin.RightTable = strings.TrimSpace(right_column[0])
outjoin.LeftColumn = strings.TrimSpace(left_column[1])
outjoin.RightColumn = strings.TrimSpace(right_column[1])
joiner = append(joiner,outjoin)
}
return joiner
} }
func _process_where(wherestr string) (where []DB_Where) { func _process_where(wherestr string) (where []DB_Where) {
@ -127,7 +199,7 @@ func _get_identifier_type(identifier string) string {
} }
func _get_identifier(segment string, startOffset int) (out string, i int) { func _get_identifier(segment string, startOffset int) (out string, i int) {
fmt.Println("entering _get_identifier") //fmt.Println("entering _get_identifier")
segment = strings.TrimSpace(segment) segment = strings.TrimSpace(segment)
segment += " " // Avoid overflow bugs with slicing segment += " " // Avoid overflow bugs with slicing
for i = startOffset; i < len(segment); i++ { for i = startOffset; i < len(segment); i++ {
@ -136,10 +208,10 @@ func _get_identifier(segment string, startOffset int) (out string, i int) {
return strings.TrimSpace(segment[startOffset:i]), (i - 1) return strings.TrimSpace(segment[startOffset:i]), (i - 1)
} }
if segment[i] == ' ' && i != startOffset { if segment[i] == ' ' && i != startOffset {
fmt.Println("segment[startOffset:i]",segment[startOffset:i]) //fmt.Println("segment[startOffset:i]",segment[startOffset:i])
fmt.Println("startOffset",startOffset) //fmt.Println("startOffset",startOffset)
fmt.Println("segment[startOffset]",string(segment[startOffset])) //fmt.Println("segment[startOffset]",string(segment[startOffset]))
fmt.Println("i",i) //fmt.Println("i",i)
return strings.TrimSpace(segment[startOffset:i]), (i - 1) return strings.TrimSpace(segment[startOffset:i]), (i - 1)
} }
} }
@ -171,3 +243,17 @@ func _skip_function_call(segment string, i int) int {
} }
return i return i
} }
func write_file(name string, content string) (err error) {
f, err := os.Create(name)
if err != nil {
return err
}
_, err = f.WriteString(content)
if err != nil {
return err
}
f.Sync()
f.Close()
return
}

View File

@ -1,7 +1,7 @@
/* WIP Under Construction */ /* WIP Under Construction */
package main package main
import "fmt" //import "fmt"
import "strings" import "strings"
import "errors" import "errors"
@ -67,7 +67,7 @@ func (adapter *Mysql_Adapter) simple_update() error {
return nil return nil
} }
func (adapter *Mysql_Adapter) simple_select(name string, table string, columns string, where string, orderby []DB_Order/*, offset int, maxCount int*/) error { func (adapter *Mysql_Adapter) simple_select(name string, table string, columns string, where string, orderby string/*, offset int, maxCount int*/) 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")
} }
@ -94,8 +94,8 @@ func (adapter *Mysql_Adapter) simple_select(name string, table string, columns s
querystr += " FROM " + table querystr += " FROM " + table
if len(where) != 0 { if len(where) != 0 {
querystr += " WHERE" querystr += " WHERE"
fmt.Println("where",where) //fmt.Println("where",where)
fmt.Println("_process_where(where)",_process_where(where)) //fmt.Println("_process_where(where)",_process_where(where))
for _, loc := range _process_where(where) { for _, loc := range _process_where(where) {
var lquote, rquote string var lquote, rquote string
if loc.LeftType == "column" { if loc.LeftType == "column" {
@ -104,25 +104,25 @@ func (adapter *Mysql_Adapter) simple_select(name string, table string, columns s
if loc.RightType == "column" { if loc.RightType == "column" {
rquote = "`" rquote = "`"
} }
querystr += " " + lquote + loc.Left + lquote + loc.Operator + " " + rquote + loc.Right + rquote + " AND " querystr += " " + lquote + loc.Left + lquote + " " + loc.Operator + " " + rquote + loc.Right + rquote + " AND "
} }
// Remove the trailing AND
querystr = querystr[0:len(querystr) - 4]
} }
// Remove the trailing AND
querystr = querystr[0:len(querystr) - 4]
if len(orderby) != 0 { if len(orderby) != 0 {
querystr += " ORDER BY " querystr += " ORDER BY "
for _, column := range orderby { for _, column := range _process_orderby(orderby) {
querystr += column.Column + " " + column.Order + "," querystr += column.Column + " " + strings.ToUpper(column.Order) + ","
} }
querystr = querystr[0:len(querystr) - 1]
} }
querystr = querystr[0:len(querystr) - 1]
adapter.write_statement(name,querystr) adapter.write_statement(name,strings.TrimSpace(querystr))
return nil return nil
} }
func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table2 string, columns string, joiners []DB_Joiner, where string, orderby []DB_Order/*, offset int, maxCount int*/) error { func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string/*, offset int, maxCount int*/) 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")
} }
@ -139,22 +139,32 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
return errors.New("No joiners found for simple_left_join") return errors.New("No joiners found for simple_left_join")
} }
// Slice up the user friendly strings into something easier to process
var colslice []string = strings.Split(strings.TrimSpace(columns),",")
var querystr string = "SELECT " var querystr string = "SELECT "
// Escape the column names, just in case we've used a reserved keyword for _, column := range _process_columns(columns) {
for _, column := range colslice { var source, alias string
querystr += "`" + strings.TrimSpace(column) + "`,"
// Escape the column names, just in case we've used a reserved keyword
if column.Table != "" {
source = "`" + column.Table + "`.`" + column.Left + "`"
} else if column.Type == "function" {
source = column.Left
} else {
source = "`" + column.Left + "`"
}
if column.Alias != "" {
alias = " AS `" + column.Alias + "`"
}
querystr += source + alias + ","
} }
// Remove the trailing comma // Remove the trailing comma
querystr = querystr[0:len(querystr) - 1] querystr = querystr[0:len(querystr) - 1]
querystr += " FROM " + table1 + " LEFT JOIN " + table2 + " ON " querystr += " FROM " + table1 + " LEFT JOIN " + table2 + " ON "
for _, joiner := range joiners { for _, joiner := range _process_joiner(joiners) {
querystr += "`" + joiner.Left + "`=`" + joiner.Right + "` AND " querystr += "`" + joiner.LeftTable + "`.`" + joiner.LeftColumn + "`=`" + joiner.RightTable + "`.`" + joiner.RightColumn + "` AND "
} }
// Remove the trailing AND // Remove the trailing AND
querystr = querystr[0:len(querystr) - 4] querystr = querystr[0:len(querystr) - 4]
@ -169,20 +179,20 @@ func (adapter *Mysql_Adapter) simple_left_join(name string, table1 string, table
if loc.RightType == "column" { if loc.RightType == "column" {
rquote = "`" rquote = "`"
} }
querystr += " " + lquote + loc.Left + lquote + loc.Operator + " " + rquote + loc.Right + rquote + " AND " querystr += " " + lquote + loc.Left + lquote + " " + loc.Operator + " " + rquote + loc.Right + rquote + " AND "
} }
querystr = querystr[0:len(querystr) - 3]
} }
querystr = querystr[0:len(querystr) - 3]
if len(orderby) != 0 { if len(orderby) != 0 {
querystr += " ORDER BY " querystr += " ORDER BY "
for _, column := range orderby { for _, column := range _process_orderby(orderby) {
querystr += column.Column + " " + column.Order + "," querystr += column.Column + " " + strings.ToUpper(column.Order) + ","
} }
querystr = querystr[0:len(querystr) - 1]
} }
querystr = querystr[0:len(querystr) - 1]
adapter.write_statement(name,querystr) adapter.write_statement(name,strings.TrimSpace(querystr))
return nil return nil
} }

View File

@ -141,7 +141,6 @@ li:hover {
width: 100%; width: 100%;
color: black; color: black;
} }
.alertItem .text.smaller { font-size: 9px; }
#footer { #footer {
clear: left; clear: left;

View File

@ -136,7 +136,6 @@ li:hover {
width: 100%; width: 100%;
color: black; color: black;
} }
.alertItem .text.smaller { font-size: 9px; }
hr { color: silver; border: 1px solid silver; } hr { color: silver; border: 1px solid silver; }

View File

@ -636,7 +636,7 @@ button.username {
li a { font-size: 14px; } li a { font-size: 14px; }
ul { height: 26px; } ul { height: 26px; }
.menu_left, .menu_right { padding-right: 7px; } .menu_left, .menu_right { padding-right: 7px; }
.menu_create_topic { display: none; } .menu_create_topic, .hide_on_mobile { display: none; }
.menu_alerts { .menu_alerts {
padding-left: 4px; padding-left: 4px;
@ -646,7 +646,6 @@ button.username {
} }
.selectedAlert .alertList { top: 33px; } .selectedAlert .alertList { top: 33px; }
.hide_on_mobile { display: none; }
.prev_button, .next_button { top: auto;bottom: 5px; } .prev_button, .next_button { top: auto;bottom: 5px; }
.colstack_grid { grid-template-columns: none; grid-gap: 8px; } .colstack_grid { grid-template-columns: none; grid-gap: 8px; }
.grid_istat { margin-bottom: 0px; } .grid_istat { margin-bottom: 0px; }
@ -672,7 +671,6 @@ button.username {
font-weight: bold; font-weight: bold;
white-space: normal; white-space: normal;
} }
.alertItem .text.smaller { font-size: 9px; }
.post_container { overflow: visible !important; } .post_container { overflow: visible !important; }
.post_item { .post_item {