Gosora now supports MSSQL (Microsoft SQL Server).
Fixed a bug with MemoryUserStore's length counter. The upsert API is currently a confusing mess, we'll have it all fixed up soon. Added the Delete method to the User struct. Improved the test coverage for the user subsystem.
This commit is contained in:
parent
fdb6304e32
commit
da6ae8d7d4
244
gen_mssql.go
244
gen_mssql.go
|
@ -113,6 +113,7 @@ var verifyEmailStmt *sql.Stmt
|
|||
var setTempGroupStmt *sql.Stmt
|
||||
var updateWordFilterStmt *sql.Stmt
|
||||
var bumpSyncStmt *sql.Stmt
|
||||
var deleteUserStmt *sql.Stmt
|
||||
var deleteReplyStmt *sql.Stmt
|
||||
var deleteProfileReplyStmt *sql.Stmt
|
||||
var deleteForumPermsByForumStmt *sql.Stmt
|
||||
|
@ -245,9 +246,9 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getUsersOffset statement.")
|
||||
getUsersOffsetStmt, err = db.Prepare("SELECT [uid],[name],[group],[active],[is_super_admin],[avatar] FROM [users] OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
getUsersOffsetStmt, err = db.Prepare("SELECT [uid],[name],[group],[active],[is_super_admin],[avatar] FROM [users] ORDER BY uid ASC OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","SELECT [uid],[name],[group],[active],[is_super_admin],[avatar] FROM [users] OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
log.Print("Bad Query: ","SELECT [uid],[name],[group],[active],[is_super_admin],[avatar] FROM [users] ORDER BY uid ASC OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -273,9 +274,9 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getModlogsOffset statement.")
|
||||
getModlogsOffsetStmt, err = db.Prepare("SELECT [action],[elementID],[elementType],[ipaddress],[actorID],[doneAt] FROM [moderation_logs] OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
getModlogsOffsetStmt, err = db.Prepare("SELECT [action],[elementID],[elementType],[ipaddress],[actorID],[doneAt] FROM [moderation_logs] ORDER BY doneAt DESC OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","SELECT [action],[elementID],[elementType],[ipaddress],[actorID],[doneAt] FROM [moderation_logs] OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
log.Print("Bad Query: ","SELECT [action],[elementID],[elementType],[ipaddress],[actorID],[doneAt] FROM [moderation_logs] ORDER BY doneAt DESC OFFSET ?1 ROWS FETCH NEXT ?2 ROWS ONLY")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -385,9 +386,9 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getTopicRepliesOffset statement.")
|
||||
getTopicRepliesOffsetStmt, err = db.Prepare("SELECT [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] FROM [replies] LEFT JOIN [users] ON [replies].[createdBy] = [users].[uid] WHERE [replies].[tid] = ?1 OFFSET ?2 ROWS FETCH NEXT ?3 ROWS ONLY")
|
||||
getTopicRepliesOffsetStmt, err = db.Prepare("SELECT [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] FROM [replies] LEFT JOIN [users] ON [replies].[createdBy] = [users].[uid] WHERE [replies].[tid] = ?1 ORDER BY replies.rid ASC OFFSET ?2 ROWS FETCH NEXT ?3 ROWS ONLY")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","SELECT [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] FROM [replies] LEFT JOIN [users] ON [replies].[createdBy] = [users].[uid] WHERE [replies].[tid] = ?1 OFFSET ?2 ROWS FETCH NEXT ?3 ROWS ONLY")
|
||||
log.Print("Bad Query: ","SELECT [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] FROM [replies] LEFT JOIN [users] ON [replies].[createdBy] = [users].[uid] WHERE [replies].[tid] = ?1 ORDER BY replies.rid ASC OFFSET ?2 ROWS FETCH NEXT ?3 ROWS ONLY")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -434,9 +435,9 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getWatchers statement.")
|
||||
getWatchersStmt, err = db.Prepare("")
|
||||
getWatchersStmt, err = db.Prepare("SELECT [activity_subscriptions].[user] FROM [activity_stream] INNER JOIN [activity_subscriptions] ON [activity_subscriptions].[targetType] = [activity_stream].[elementType] AND [activity_subscriptions].[targetID] = [activity_stream].[elementID] AND [activity_subscriptions].[user] != [activity_stream].[actor] WHERE [asid] = ?1")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","SELECT [activity_subscriptions].[user] FROM [activity_stream] INNER JOIN [activity_subscriptions] ON [activity_subscriptions].[targetType] = [activity_stream].[elementType] AND [activity_subscriptions].[targetID] = [activity_stream].[elementID] AND [activity_subscriptions].[user] != [activity_stream].[actor] WHERE [asid] = ?1")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -448,23 +449,23 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing createReport statement.")
|
||||
createReportStmt, err = db.Prepare("INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[createdBy],[data],[parentID],[css_class]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,1,'report')")
|
||||
createReportStmt, err = db.Prepare("INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[createdBy],[lastReplyBy],[data],[parentID],[css_class]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,1,'report')")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[createdBy],[data],[parentID],[css_class]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,1,'report')")
|
||||
log.Print("Bad Query: ","INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[createdBy],[lastReplyBy],[data],[parentID],[css_class]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,1,'report')")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing createReply statement.")
|
||||
createReplyStmt, err = db.Prepare("INSERT INTO [replies] ([tid],[content],[parsed_content],[createdAt],[ipaddress],[words],[createdBy]) VALUES (?,?,?,GETUTCDATE(),?,?,?)")
|
||||
createReplyStmt, err = db.Prepare("INSERT INTO [replies] ([tid],[content],[parsed_content],[createdAt],[lastUpdated],[ipaddress],[words],[createdBy]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?)")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","INSERT INTO [replies] ([tid],[content],[parsed_content],[createdAt],[ipaddress],[words],[createdBy]) VALUES (?,?,?,GETUTCDATE(),?,?,?)")
|
||||
log.Print("Bad Query: ","INSERT INTO [replies] ([tid],[content],[parsed_content],[createdAt],[lastUpdated],[ipaddress],[words],[createdBy]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?)")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing createActionReply statement.")
|
||||
createActionReplyStmt, err = db.Prepare("INSERT INTO [replies] ([tid],[actionType],[ipaddress],[createdBy]) VALUES (?,?,?,?)")
|
||||
createActionReplyStmt, err = db.Prepare("INSERT INTO [replies] ([tid],[actionType],[ipaddress],[createdBy],[createdAt],[lastUpdated],[content],[parsed_content]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),'','')")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","INSERT INTO [replies] ([tid],[actionType],[ipaddress],[createdBy]) VALUES (?,?,?,?)")
|
||||
log.Print("Bad Query: ","INSERT INTO [replies] ([tid],[actionType],[ipaddress],[createdBy],[createdAt],[lastUpdated],[content],[parsed_content]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),'','')")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -574,338 +575,345 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing addForumPermsToGroup statement.")
|
||||
addForumPermsToGroupStmt, err = db.Prepare("")
|
||||
addForumPermsToGroupStmt, err = db.Prepare("MERGE [forums_permissions] WITH(HOLDLOCK) as t1 USING (VALUES(?,?,?,?)) AS updates (f0,f1,f2,f3) ON [gid] = ? [fid] = ? WHEN MATCHED THEN UPDATE SET [gid] = f0,[fid] = f1,[preset] = f2,[permissions] = f3 WHEN NOT MATCHED THEN INSERT([gid],[fid],[preset],[permissions]) VALUES (f0,f1,f2,f3);")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","MERGE [forums_permissions] WITH(HOLDLOCK) as t1 USING (VALUES(?,?,?,?)) AS updates (f0,f1,f2,f3) ON [gid] = ? [fid] = ? WHEN MATCHED THEN UPDATE SET [gid] = f0,[fid] = f1,[preset] = f2,[permissions] = f3 WHEN NOT MATCHED THEN INSERT([gid],[fid],[preset],[permissions]) VALUES (f0,f1,f2,f3);")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing replaceScheduleGroup statement.")
|
||||
replaceScheduleGroupStmt, err = db.Prepare("")
|
||||
replaceScheduleGroupStmt, err = db.Prepare("MERGE [users_groups_scheduler] WITH(HOLDLOCK) as t1 USING (VALUES(?,?,?,GETUTCDATE(),?,?)) AS updates (f0,f1,f2,f3,f4,f5) ON [uid] = ? WHEN MATCHED THEN UPDATE SET [uid] = f0,[set_group] = f1,[issued_by] = f2,[issued_at] = f3,[revert_at] = f4,[temporary] = f5 WHEN NOT MATCHED THEN INSERT([uid],[set_group],[issued_by],[issued_at],[revert_at],[temporary]) VALUES (f0,f1,f2,f3,f4,f5);")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","MERGE [users_groups_scheduler] WITH(HOLDLOCK) as t1 USING (VALUES(?,?,?,GETUTCDATE(),?,?)) AS updates (f0,f1,f2,f3,f4,f5) ON [uid] = ? WHEN MATCHED THEN UPDATE SET [uid] = f0,[set_group] = f1,[issued_by] = f2,[issued_at] = f3,[revert_at] = f4,[temporary] = f5 WHEN NOT MATCHED THEN INSERT([uid],[set_group],[issued_by],[issued_at],[revert_at],[temporary]) VALUES (f0,f1,f2,f3,f4,f5);")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing addRepliesToTopic statement.")
|
||||
addRepliesToTopicStmt, err = db.Prepare("")
|
||||
addRepliesToTopicStmt, err = db.Prepare("UPDATE [topics] SET [postCount] = [postCount] + ?,[lastReplyBy] = ?,[lastReplyAt] = GETUTCDATE() WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [postCount] = [postCount] + ?,[lastReplyBy] = ?,[lastReplyAt] = GETUTCDATE() WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing removeRepliesFromTopic statement.")
|
||||
removeRepliesFromTopicStmt, err = db.Prepare("")
|
||||
removeRepliesFromTopicStmt, err = db.Prepare("UPDATE [topics] SET [postCount] = [postCount] - ? WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [postCount] = [postCount] - ? WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing addTopicsToForum statement.")
|
||||
addTopicsToForumStmt, err = db.Prepare("")
|
||||
addTopicsToForumStmt, err = db.Prepare("UPDATE [forums] SET [topicCount] = [topicCount] + ? WHERE [fid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [forums] SET [topicCount] = [topicCount] + ? WHERE [fid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing removeTopicsFromForum statement.")
|
||||
removeTopicsFromForumStmt, err = db.Prepare("")
|
||||
removeTopicsFromForumStmt, err = db.Prepare("UPDATE [forums] SET [topicCount] = [topicCount] - ? WHERE [fid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [forums] SET [topicCount] = [topicCount] - ? WHERE [fid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateForumCache statement.")
|
||||
updateForumCacheStmt, err = db.Prepare("")
|
||||
updateForumCacheStmt, err = db.Prepare("UPDATE [forums] SET [lastTopicID] = ?,[lastReplyerID] = ? WHERE [fid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [forums] SET [lastTopicID] = ?,[lastReplyerID] = ? WHERE [fid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing addLikesToTopic statement.")
|
||||
addLikesToTopicStmt, err = db.Prepare("")
|
||||
addLikesToTopicStmt, err = db.Prepare("UPDATE [topics] SET [likeCount] = [likeCount] + ? WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [likeCount] = [likeCount] + ? WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing addLikesToReply statement.")
|
||||
addLikesToReplyStmt, err = db.Prepare("")
|
||||
addLikesToReplyStmt, err = db.Prepare("UPDATE [replies] SET [likeCount] = [likeCount] + ? WHERE [rid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [replies] SET [likeCount] = [likeCount] + ? WHERE [rid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing editTopic statement.")
|
||||
editTopicStmt, err = db.Prepare("")
|
||||
editTopicStmt, err = db.Prepare("UPDATE [topics] SET [title] = ?,[content] = ?,[parsed_content] = ? WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [title] = ?,[content] = ?,[parsed_content] = ? WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing editReply statement.")
|
||||
editReplyStmt, err = db.Prepare("")
|
||||
editReplyStmt, err = db.Prepare("UPDATE [replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing stickTopic statement.")
|
||||
stickTopicStmt, err = db.Prepare("")
|
||||
stickTopicStmt, err = db.Prepare("UPDATE [topics] SET [sticky] = 1 WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [sticky] = 1 WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing unstickTopic statement.")
|
||||
unstickTopicStmt, err = db.Prepare("")
|
||||
unstickTopicStmt, err = db.Prepare("UPDATE [topics] SET [sticky] = 0 WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [sticky] = 0 WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing lockTopic statement.")
|
||||
lockTopicStmt, err = db.Prepare("")
|
||||
lockTopicStmt, err = db.Prepare("UPDATE [topics] SET [is_closed] = 1 WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [is_closed] = 1 WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing unlockTopic statement.")
|
||||
unlockTopicStmt, err = db.Prepare("")
|
||||
unlockTopicStmt, err = db.Prepare("UPDATE [topics] SET [is_closed] = 0 WHERE [tid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [topics] SET [is_closed] = 0 WHERE [tid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateLastIP statement.")
|
||||
updateLastIPStmt, err = db.Prepare("")
|
||||
updateLastIPStmt, err = db.Prepare("UPDATE [users] SET [last_ip] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [last_ip] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateSession statement.")
|
||||
updateSessionStmt, err = db.Prepare("")
|
||||
updateSessionStmt, err = db.Prepare("UPDATE [users] SET [session] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [session] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing setPassword statement.")
|
||||
setPasswordStmt, err = db.Prepare("")
|
||||
setPasswordStmt, err = db.Prepare("UPDATE [users] SET [password] = ?,[salt] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [password] = ?,[salt] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing setAvatar statement.")
|
||||
setAvatarStmt, err = db.Prepare("")
|
||||
setAvatarStmt, err = db.Prepare("UPDATE [users] SET [avatar] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [avatar] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing setUsername statement.")
|
||||
setUsernameStmt, err = db.Prepare("")
|
||||
setUsernameStmt, err = db.Prepare("UPDATE [users] SET [name] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [name] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing changeGroup statement.")
|
||||
changeGroupStmt, err = db.Prepare("")
|
||||
changeGroupStmt, err = db.Prepare("UPDATE [users] SET [group] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [group] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing activateUser statement.")
|
||||
activateUserStmt, err = db.Prepare("")
|
||||
activateUserStmt, err = db.Prepare("UPDATE [users] SET [active] = 1 WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [active] = 1 WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateUserLevel statement.")
|
||||
updateUserLevelStmt, err = db.Prepare("")
|
||||
updateUserLevelStmt, err = db.Prepare("UPDATE [users] SET [level] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [level] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing incrementUserScore statement.")
|
||||
incrementUserScoreStmt, err = db.Prepare("")
|
||||
incrementUserScoreStmt, err = db.Prepare("UPDATE [users] SET [score] = [score] + ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [score] = [score] + ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing incrementUserPosts statement.")
|
||||
incrementUserPostsStmt, err = db.Prepare("")
|
||||
incrementUserPostsStmt, err = db.Prepare("UPDATE [users] SET [posts] = [posts] + ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [posts] = [posts] + ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing incrementUserBigposts statement.")
|
||||
incrementUserBigpostsStmt, err = db.Prepare("")
|
||||
incrementUserBigpostsStmt, err = db.Prepare("UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing incrementUserMegaposts statement.")
|
||||
incrementUserMegapostsStmt, err = db.Prepare("")
|
||||
incrementUserMegapostsStmt, err = db.Prepare("UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ?,[megaposts] = [megaposts] + ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [posts] = [posts] + ?,[bigposts] = [bigposts] + ?,[megaposts] = [megaposts] + ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing incrementUserTopics statement.")
|
||||
incrementUserTopicsStmt, err = db.Prepare("")
|
||||
incrementUserTopicsStmt, err = db.Prepare("UPDATE [users] SET [topics] = [topics] + ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [topics] = [topics] + ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing editProfileReply statement.")
|
||||
editProfileReplyStmt, err = db.Prepare("")
|
||||
editProfileReplyStmt, err = db.Prepare("UPDATE [users_replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users_replies] SET [content] = ?,[parsed_content] = ? WHERE [rid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateForum statement.")
|
||||
updateForumStmt, err = db.Prepare("")
|
||||
updateForumStmt, err = db.Prepare("UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [forums] SET [name] = ?,[desc] = ?,[active] = ?,[preset] = ? WHERE [fid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateSetting statement.")
|
||||
updateSettingStmt, err = db.Prepare("")
|
||||
updateSettingStmt, err = db.Prepare("UPDATE [settings] SET [content] = ? WHERE [name] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [settings] SET [content] = ? WHERE [name] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updatePlugin statement.")
|
||||
updatePluginStmt, err = db.Prepare("")
|
||||
updatePluginStmt, err = db.Prepare("UPDATE [plugins] SET [active] = ? WHERE [uname] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [plugins] SET [active] = ? WHERE [uname] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updatePluginInstall statement.")
|
||||
updatePluginInstallStmt, err = db.Prepare("")
|
||||
updatePluginInstallStmt, err = db.Prepare("UPDATE [plugins] SET [installed] = ? WHERE [uname] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [plugins] SET [installed] = ? WHERE [uname] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateTheme statement.")
|
||||
updateThemeStmt, err = db.Prepare("")
|
||||
updateThemeStmt, err = db.Prepare("UPDATE [themes] SET [default] = ? WHERE [uname] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [themes] SET [default] = ? WHERE [uname] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateUser statement.")
|
||||
updateUserStmt, err = db.Prepare("")
|
||||
updateUserStmt, err = db.Prepare("UPDATE [users] SET [name] = ?,[email] = ?,[group] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [name] = ?,[email] = ?,[group] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateGroupPerms statement.")
|
||||
updateGroupPermsStmt, err = db.Prepare("")
|
||||
updateGroupPermsStmt, err = db.Prepare("UPDATE [users_groups] SET [permissions] = ? WHERE [gid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users_groups] SET [permissions] = ? WHERE [gid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateGroupRank statement.")
|
||||
updateGroupRankStmt, err = db.Prepare("")
|
||||
updateGroupRankStmt, err = db.Prepare("UPDATE [users_groups] SET [is_admin] = ?,[is_mod] = ?,[is_banned] = ? WHERE [gid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users_groups] SET [is_admin] = ?,[is_mod] = ?,[is_banned] = ? WHERE [gid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateGroup statement.")
|
||||
updateGroupStmt, err = db.Prepare("")
|
||||
updateGroupStmt, err = db.Prepare("UPDATE [users_groups] SET [name] = ?,[tag] = ? WHERE [gid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users_groups] SET [name] = ?,[tag] = ? WHERE [gid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateEmail statement.")
|
||||
updateEmailStmt, err = db.Prepare("")
|
||||
updateEmailStmt, err = db.Prepare("UPDATE [emails] SET [email] = ?,[uid] = ?,[validated] = ?,[token] = ? WHERE [email] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [emails] SET [email] = ?,[uid] = ?,[validated] = ?,[token] = ? WHERE [email] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing verifyEmail statement.")
|
||||
verifyEmailStmt, err = db.Prepare("")
|
||||
verifyEmailStmt, err = db.Prepare("UPDATE [emails] SET [validated] = 1,[token] = '' WHERE [email] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [emails] SET [validated] = 1,[token] = '' WHERE [email] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing setTempGroup statement.")
|
||||
setTempGroupStmt, err = db.Prepare("")
|
||||
setTempGroupStmt, err = db.Prepare("UPDATE [users] SET [temp_group] = ? WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [users] SET [temp_group] = ? WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing updateWordFilter statement.")
|
||||
updateWordFilterStmt, err = db.Prepare("")
|
||||
updateWordFilterStmt, err = db.Prepare("UPDATE [word_filters] SET [find] = ?,[replacement] = ? WHERE [wfid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [word_filters] SET [find] = ?,[replacement] = ? WHERE [wfid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing bumpSync statement.")
|
||||
bumpSyncStmt, err = db.Prepare("")
|
||||
bumpSyncStmt, err = db.Prepare("UPDATE [sync] SET [last_update] = GETUTCDATE()")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","UPDATE [sync] SET [last_update] = GETUTCDATE()")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteUser statement.")
|
||||
deleteUserStmt, err = db.Prepare("DELETE FROM [users] WHERE [uid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","DELETE FROM [users] WHERE [uid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteReply statement.")
|
||||
deleteReplyStmt, err = db.Prepare("")
|
||||
deleteReplyStmt, err = db.Prepare("DELETE FROM [replies] WHERE [rid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","DELETE FROM [replies] WHERE [rid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteProfileReply statement.")
|
||||
deleteProfileReplyStmt, err = db.Prepare("")
|
||||
deleteProfileReplyStmt, err = db.Prepare("DELETE FROM [users_replies] WHERE [rid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","DELETE FROM [users_replies] WHERE [rid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteForumPermsByForum statement.")
|
||||
deleteForumPermsByForumStmt, err = db.Prepare("")
|
||||
deleteForumPermsByForumStmt, err = db.Prepare("DELETE FROM [forums_permissions] WHERE [fid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","DELETE FROM [forums_permissions] WHERE [fid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteActivityStreamMatch statement.")
|
||||
deleteActivityStreamMatchStmt, err = db.Prepare("")
|
||||
deleteActivityStreamMatchStmt, err = db.Prepare("DELETE FROM [activity_stream_matches] WHERE [watcher] = ? AND [asid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","DELETE FROM [activity_stream_matches] WHERE [watcher] = ? AND [asid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteWordFilter statement.")
|
||||
deleteWordFilterStmt, err = db.Prepare("")
|
||||
deleteWordFilterStmt, err = db.Prepare("DELETE FROM [word_filters] WHERE [wfid] = ?")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","DELETE FROM [word_filters] WHERE [wfid] = ?")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -931,30 +939,30 @@ func _gen_mssql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing addForumPermsToForumAdmins statement.")
|
||||
addForumPermsToForumAdminsStmt, err = db.Prepare("")
|
||||
addForumPermsToForumAdminsStmt, err = db.Prepare("INSERT INTO [forums_permissions] ([gid],[fid],[preset],[permissions]) SELECT [gid],[? AS fid],[? AS preset],[? AS permissions] FROM [users_groups] WHERE [is_admin] = 1")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","INSERT INTO [forums_permissions] ([gid],[fid],[preset],[permissions]) SELECT [gid],[? AS fid],[? AS preset],[? AS permissions] FROM [users_groups] WHERE [is_admin] = 1")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing addForumPermsToForumStaff statement.")
|
||||
addForumPermsToForumStaffStmt, err = db.Prepare("")
|
||||
addForumPermsToForumStaffStmt, err = db.Prepare("INSERT INTO [forums_permissions] ([gid],[fid],[preset],[permissions]) SELECT [gid],[? AS fid],[? AS preset],[? AS permissions] FROM [users_groups] WHERE [is_admin] = 0 AND [is_mod] = 1")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","INSERT INTO [forums_permissions] ([gid],[fid],[preset],[permissions]) SELECT [gid],[? AS fid],[? AS preset],[? AS permissions] FROM [users_groups] WHERE [is_admin] = 0 AND [is_mod] = 1")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing addForumPermsToForumMembers statement.")
|
||||
addForumPermsToForumMembersStmt, err = db.Prepare("")
|
||||
addForumPermsToForumMembersStmt, err = db.Prepare("INSERT INTO [forums_permissions] ([gid],[fid],[preset],[permissions]) SELECT [gid],[? AS fid],[? AS preset],[? AS permissions] FROM [users_groups] WHERE [is_admin] = 0 AND [is_mod] = 0 AND [is_banned] = 0")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","INSERT INTO [forums_permissions] ([gid],[fid],[preset],[permissions]) SELECT [gid],[? AS fid],[? AS preset],[? AS permissions] FROM [users_groups] WHERE [is_admin] = 0 AND [is_mod] = 0 AND [is_banned] = 0")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing notifyWatchers statement.")
|
||||
notifyWatchersStmt, err = db.Prepare("")
|
||||
notifyWatchersStmt, err = db.Prepare("INSERT INTO [activity_stream_matches] ([watcher],[asid]) SELECT [activity_subscriptions].[user],[activity_stream].[asid] FROM [activity_stream] INNER JOIN [activity_subscriptions] ON [activity_subscriptions].[targetType] = [activity_stream].[elementType] AND [activity_subscriptions].[targetID] = [activity_stream].[elementID] AND [activity_subscriptions].[user] != [activity_stream].[actor] WHERE [asid] = ?1")
|
||||
if err != nil {
|
||||
log.Print("Bad Query: ","")
|
||||
log.Print("Bad Query: ","INSERT INTO [activity_stream_matches] ([watcher],[asid]) SELECT [activity_subscriptions].[user],[activity_stream].[asid] FROM [activity_stream] INNER JOIN [activity_subscriptions] ON [activity_subscriptions].[targetType] = [activity_stream].[elementType] AND [activity_subscriptions].[targetID] = [activity_stream].[elementID] AND [activity_subscriptions].[user] != [activity_stream].[actor] WHERE [asid] = ?1")
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
28
gen_mysql.go
28
gen_mysql.go
|
@ -6,6 +6,7 @@ package main
|
|||
|
||||
import "log"
|
||||
import "database/sql"
|
||||
import "./query_gen/lib"
|
||||
|
||||
// nolint
|
||||
var getUserStmt *sql.Stmt
|
||||
|
@ -71,8 +72,8 @@ var addModlogEntryStmt *sql.Stmt
|
|||
var addAdminlogEntryStmt *sql.Stmt
|
||||
var addAttachmentStmt *sql.Stmt
|
||||
var createWordFilterStmt *sql.Stmt
|
||||
var addForumPermsToGroupStmt *sql.Stmt
|
||||
var replaceScheduleGroupStmt *sql.Stmt
|
||||
var addForumPermsToGroupStmt *qgen.MySQLUpsertCallback
|
||||
var replaceScheduleGroupStmt *qgen.MySQLUpsertCallback
|
||||
var addRepliesToTopicStmt *sql.Stmt
|
||||
var removeRepliesFromTopicStmt *sql.Stmt
|
||||
var addTopicsToForumStmt *sql.Stmt
|
||||
|
@ -114,6 +115,7 @@ var verifyEmailStmt *sql.Stmt
|
|||
var setTempGroupStmt *sql.Stmt
|
||||
var updateWordFilterStmt *sql.Stmt
|
||||
var bumpSyncStmt *sql.Stmt
|
||||
var deleteUserStmt *sql.Stmt
|
||||
var deleteReplyStmt *sql.Stmt
|
||||
var deleteProfileReplyStmt *sql.Stmt
|
||||
var deleteForumPermsByForumStmt *sql.Stmt
|
||||
|
@ -230,7 +232,7 @@ func _gen_mysql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getUsersOffset statement.")
|
||||
getUsersOffsetStmt, err = db.Prepare("SELECT `uid`,`name`,`group`,`active`,`is_super_admin`,`avatar` FROM `users` LIMIT ?,?")
|
||||
getUsersOffsetStmt, err = db.Prepare("SELECT `uid`,`name`,`group`,`active`,`is_super_admin`,`avatar` FROM `users` ORDER BY uid ASC LIMIT ?,?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -254,7 +256,7 @@ func _gen_mysql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getModlogsOffset statement.")
|
||||
getModlogsOffsetStmt, err = db.Prepare("SELECT `action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt` FROM `moderation_logs` LIMIT ?,?")
|
||||
getModlogsOffsetStmt, err = db.Prepare("SELECT `action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt` FROM `moderation_logs` ORDER BY doneAt DESC LIMIT ?,?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -350,7 +352,7 @@ func _gen_mysql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing getTopicRepliesOffset statement.")
|
||||
getTopicRepliesOffsetStmt, err = db.Prepare("SELECT `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` FROM `replies` LEFT JOIN `users` ON `replies`.`createdBy` = `users`.`uid` WHERE `replies`.`tid` = ? LIMIT ?,?")
|
||||
getTopicRepliesOffsetStmt, err = db.Prepare("SELECT `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` FROM `replies` LEFT JOIN `users` ON `replies`.`createdBy` = `users`.`uid` WHERE `replies`.`tid` = ? ORDER BY replies.rid ASC LIMIT ?,?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -404,19 +406,19 @@ func _gen_mysql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing createReport statement.")
|
||||
createReportStmt, err = db.Prepare("INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`createdBy`,`data`,`parentID`,`css_class`) VALUES (?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,1,'report')")
|
||||
createReportStmt, err = db.Prepare("INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`createdBy`,`lastReplyBy`,`data`,`parentID`,`css_class`) VALUES (?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing createReply statement.")
|
||||
createReplyStmt, err = db.Prepare("INSERT INTO `replies`(`tid`,`content`,`parsed_content`,`createdAt`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,UTC_TIMESTAMP(),?,?,?)")
|
||||
createReplyStmt, err = db.Prepare("INSERT INTO `replies`(`tid`,`content`,`parsed_content`,`createdAt`,`lastUpdated`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing createActionReply statement.")
|
||||
createActionReplyStmt, err = db.Prepare("INSERT INTO `replies`(`tid`,`actionType`,`ipaddress`,`createdBy`) VALUES (?,?,?,?)")
|
||||
createActionReplyStmt, err = db.Prepare("INSERT INTO `replies`(`tid`,`actionType`,`ipaddress`,`createdBy`,`createdAt`,`lastUpdated`,`content`,`parsed_content`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'','')")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -512,13 +514,13 @@ func _gen_mysql() (err error) {
|
|||
}
|
||||
|
||||
log.Print("Preparing addForumPermsToGroup statement.")
|
||||
addForumPermsToGroupStmt, err = db.Prepare("REPLACE INTO `forums_permissions`(`gid`,`fid`,`preset`,`permissions`) VALUES (?,?,?,?)")
|
||||
addForumPermsToGroupStmt, err = qgen.PrepareMySQLUpsertCallback(db, "INSERT INTO `forums_permissions`(`gid`,`fid`,`preset`,`permissions`) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE `gid` = ? AND `fid` = ? AND `preset` = ? AND `permissions` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing replaceScheduleGroup statement.")
|
||||
replaceScheduleGroupStmt, err = db.Prepare("REPLACE INTO `users_groups_scheduler`(`uid`,`set_group`,`issued_by`,`issued_at`,`revert_at`,`temporary`) VALUES (?,?,?,UTC_TIMESTAMP(),?,?)")
|
||||
replaceScheduleGroupStmt, err = qgen.PrepareMySQLUpsertCallback(db, "INSERT INTO `users_groups_scheduler`(`uid`,`set_group`,`issued_by`,`issued_at`,`revert_at`,`temporary`) VALUES (?,?,?,UTC_TIMESTAMP(),?,?) ON DUPLICATE KEY UPDATE `uid` = ? AND `set_group` = ? AND `issued_by` = ? AND `issued_at` = UTC_TIMESTAMP() AND `revert_at` = ? AND `temporary` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -769,6 +771,12 @@ func _gen_mysql() (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteUser statement.")
|
||||
deleteUserStmt, err = db.Prepare("DELETE FROM `users` WHERE `uid` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing deleteReply statement.")
|
||||
deleteReplyStmt, err = db.Prepare("DELETE FROM `replies` WHERE `rid` = ?")
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// Generated by Gosora's Query Generator. DO NOT EDIT.
|
||||
package main
|
||||
|
||||
var dbTablePrimaryKeys = map[string]string{
|
||||
"forums":"fid",
|
||||
"topics":"tid",
|
||||
"attachments":"attachID",
|
||||
"users_replies":"rid",
|
||||
"word_filters":"wfid",
|
||||
"users":"uid",
|
||||
"users_groups":"gid",
|
||||
"users_groups_scheduler":"uid",
|
||||
"replies":"rid",
|
||||
"activity_stream":"asid",
|
||||
}
|
|
@ -24,6 +24,26 @@ import (
|
|||
//var dbTest *sql.DB
|
||||
var dbProd *sql.DB
|
||||
var gloinited bool
|
||||
var installAdapter install.InstallAdapter
|
||||
|
||||
func ResetTables() (err error) {
|
||||
err = installAdapter.InitDatabase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = installAdapter.TableDefs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = installAdapter.CreateAdmin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return installAdapter.InitialData()
|
||||
}
|
||||
|
||||
func gloinit() (err error) {
|
||||
dev.DebugMode = false
|
||||
|
@ -42,28 +62,14 @@ func gloinit() (err error) {
|
|||
|
||||
switchToTestDB()
|
||||
|
||||
adap, ok := install.Lookup(dbAdapter)
|
||||
var ok bool
|
||||
installAdapter, ok = install.Lookup(dbAdapter)
|
||||
if !ok {
|
||||
return errors.New("We couldn't find the adapter '" + dbAdapter + "'")
|
||||
}
|
||||
adap.SetConfig(dbConfig.Host, dbConfig.Username, dbConfig.Password, dbConfig.Dbname, dbConfig.Port)
|
||||
installAdapter.SetConfig(dbConfig.Host, dbConfig.Username, dbConfig.Password, dbConfig.Dbname, dbConfig.Port)
|
||||
|
||||
err = adap.InitDatabase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = adap.TableDefs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = adap.CreateAdmin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = adap.InitialData()
|
||||
err = ResetTables()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -110,6 +116,7 @@ func gloinit() (err error) {
|
|||
func init() {
|
||||
err := gloinit()
|
||||
if err != nil {
|
||||
log.Print("Something bad happened")
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,13 @@ func (ins *MssqlInstaller) TableDefs() (err error) {
|
|||
}
|
||||
table = strings.TrimSuffix(table, ext)
|
||||
|
||||
// ? - This is mainly here for tests, although it might allow the installer to overwrite a production database, so we might want to proceed with caution
|
||||
_, err = ins.db.Exec("DROP TABLE IF EXISTS [" + table + "];")
|
||||
if err != nil {
|
||||
fmt.Println("Failed query:", "DROP TABLE IF EXISTS ["+table+"]")
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Creating table '" + table + "'")
|
||||
data, err := ioutil.ReadFile("./schema/mssql/" + f.Name())
|
||||
if err != nil {
|
||||
|
|
|
@ -758,7 +758,7 @@ func routeReportSubmit(w http.ResponseWriter, r *http.Request, user User, sitemI
|
|||
|
||||
// TODO: Repost attachments in the reports forum, so that the mods can see them
|
||||
// ? - Can we do this via the TopicStore?
|
||||
res, err := createReportStmt.Exec(title, content, parseMessage(content, 0, ""), user.ID, itemType+"_"+strconv.Itoa(itemID))
|
||||
res, err := createReportStmt.Exec(title, content, parseMessage(content, 0, ""), user.ID, user.ID, itemType+"_"+strconv.Itoa(itemID))
|
||||
if err != nil {
|
||||
InternalError(err, w)
|
||||
return
|
||||
|
|
290
misc_test.go
290
misc_test.go
|
@ -1,10 +1,29 @@
|
|||
package main
|
||||
|
||||
import "strconv"
|
||||
import "testing"
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func recordMustExist(t *testing.T, err error, errmsg string) {
|
||||
if err == ErrNoRows {
|
||||
t.Error(errmsg)
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func recordMustNotExist(t *testing.T, err error, errmsg string) {
|
||||
if err == nil {
|
||||
t.Error(errmsg)
|
||||
} else if err != ErrNoRows {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Generate a test database to work with rather than a live one
|
||||
// TODO: We might need to refactor TestUserStore soon, as it's getting fairly complex
|
||||
func TestUserStore(t *testing.T) {
|
||||
if !gloinited {
|
||||
err := gloinit()
|
||||
|
@ -18,14 +37,13 @@ func TestUserStore(t *testing.T) {
|
|||
|
||||
users = NewMemoryUserStore(config.UserCacheCapacity)
|
||||
users.(UserCache).Flush()
|
||||
userStoreTest(t)
|
||||
userStoreTest(t, 2)
|
||||
users = NewSQLUserStore()
|
||||
userStoreTest(t)
|
||||
userStoreTest(t, 3)
|
||||
}
|
||||
func userStoreTest(t *testing.T) {
|
||||
func userStoreTest(t *testing.T, newUserID int) {
|
||||
var user *User
|
||||
var err error
|
||||
var length int
|
||||
|
||||
ucache, hasCache := users.(UserCache)
|
||||
if hasCache && ucache.Length() != 0 {
|
||||
|
@ -33,60 +51,57 @@ func userStoreTest(t *testing.T) {
|
|||
}
|
||||
|
||||
_, err = users.Get(-1)
|
||||
if err == nil {
|
||||
t.Error("UID #-1 shouldn't exist")
|
||||
} else if err != ErrNoRows {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustNotExist(t, err, "UID #-1 shouldn't exist")
|
||||
|
||||
if hasCache && ucache.Length() != 0 {
|
||||
t.Error("There shouldn't be anything in the user cache")
|
||||
}
|
||||
|
||||
_, err = users.Get(0)
|
||||
if err == nil {
|
||||
t.Error("UID #0 shouldn't exist")
|
||||
} else if err != ErrNoRows {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustNotExist(t, err, "UID #0 shouldn't exist")
|
||||
|
||||
if hasCache && ucache.Length() != 0 {
|
||||
t.Error("There shouldn't be anything in the user cache")
|
||||
}
|
||||
|
||||
user, err = users.Get(1)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find UID #1")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find UID #1")
|
||||
|
||||
if user.ID != 1 {
|
||||
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
|
||||
}
|
||||
if user.Name != "Admin" {
|
||||
t.Error("user.Name should be 'Admin', not '" + user.Name + "'")
|
||||
}
|
||||
if user.Group != 1 {
|
||||
t.Error("Admin should be in group 1")
|
||||
}
|
||||
|
||||
user, err = users.Get(newUserID)
|
||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't exist", newUserID))
|
||||
|
||||
if hasCache {
|
||||
length = ucache.Length()
|
||||
if length != 1 {
|
||||
t.Error("User cache length should be 1, not " + strconv.Itoa(length))
|
||||
}
|
||||
expectIntToBeX(t, ucache.Length(), 1, "User cache length should be 1, not %d")
|
||||
|
||||
user, err = ucache.CacheGet(-1)
|
||||
recordMustNotExist(t, err, "UID #-1 shouldn't exist, even in the cache")
|
||||
user, err = ucache.CacheGet(0)
|
||||
recordMustNotExist(t, err, "UID #0 shouldn't exist, even in the cache")
|
||||
user, err = ucache.CacheGet(1)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find UID #1 in the cache")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find UID #1 in the cache")
|
||||
|
||||
if user.ID != 1 {
|
||||
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
|
||||
}
|
||||
if user.Name != "Admin" {
|
||||
t.Error("user.Name should be 'Admin', not '" + user.Name + "'")
|
||||
}
|
||||
|
||||
user, err = ucache.CacheGet(newUserID)
|
||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't exist, even in the cache", newUserID))
|
||||
|
||||
ucache.Flush()
|
||||
length = ucache.Length()
|
||||
if length != 0 {
|
||||
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
|
||||
}
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
}
|
||||
|
||||
// TODO: Lock onto the specific error type. Is this even possible without sacrificing the detailed information in the error message?
|
||||
|
@ -97,10 +112,7 @@ func userStoreTest(t *testing.T) {
|
|||
}
|
||||
|
||||
if hasCache {
|
||||
length = ucache.Length()
|
||||
if length != 0 {
|
||||
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
|
||||
}
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
}
|
||||
|
||||
userList, _ = users.BulkGetMap([]int{0})
|
||||
|
@ -109,10 +121,7 @@ func userStoreTest(t *testing.T) {
|
|||
}
|
||||
|
||||
if hasCache {
|
||||
length = ucache.Length()
|
||||
if length != 0 {
|
||||
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
|
||||
}
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
}
|
||||
|
||||
userList, _ = users.BulkGetMap([]int{1})
|
||||
|
@ -133,17 +142,9 @@ func userStoreTest(t *testing.T) {
|
|||
}
|
||||
|
||||
if hasCache {
|
||||
length = ucache.Length()
|
||||
if length != 1 {
|
||||
t.Error("User cache length should be 1, not " + strconv.Itoa(length))
|
||||
}
|
||||
|
||||
expectIntToBeX(t, ucache.Length(), 1, "User cache length should be 1, not %d")
|
||||
user, err = ucache.CacheGet(1)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find UID #1 in the cache")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find UID #1 in the cache")
|
||||
|
||||
if user.ID != 1 {
|
||||
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
|
||||
|
@ -152,32 +153,138 @@ func userStoreTest(t *testing.T) {
|
|||
ucache.Flush()
|
||||
}
|
||||
|
||||
ok = users.Exists(-1)
|
||||
if ok {
|
||||
t.Error("UID #-1 shouldn't exist")
|
||||
}
|
||||
|
||||
ok = users.Exists(0)
|
||||
if ok {
|
||||
t.Error("UID #0 shouldn't exist")
|
||||
}
|
||||
|
||||
ok = users.Exists(1)
|
||||
if !ok {
|
||||
t.Error("UID #1 should exist")
|
||||
}
|
||||
expect(t, !users.Exists(-1), "UID #-1 shouldn't exist")
|
||||
expect(t, !users.Exists(0), "UID #0 shouldn't exist")
|
||||
expect(t, users.Exists(1), "UID #1 should exist")
|
||||
expect(t, !users.Exists(newUserID), fmt.Sprintf("UID #%d shouldn't exist", newUserID))
|
||||
|
||||
if hasCache {
|
||||
length = ucache.Length()
|
||||
if length != 0 {
|
||||
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
}
|
||||
expectIntToBeX(t, users.GlobalCount(), 1, "The number of users should be one, not %d")
|
||||
|
||||
var awaitingActivation = 5
|
||||
uid, err := users.Create("Sam", "ReallyBadPassword", "sam@localhost.loc", awaitingActivation, 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if uid != newUserID {
|
||||
t.Errorf("The UID of the new user should be %d", newUserID)
|
||||
}
|
||||
if !users.Exists(newUserID) {
|
||||
t.Errorf("UID #%d should exist", newUserID)
|
||||
}
|
||||
|
||||
user, err = users.Get(newUserID)
|
||||
recordMustExist(t, err, fmt.Sprintf("Couldn't find UID #%d", newUserID))
|
||||
if user.ID != newUserID {
|
||||
t.Errorf("The UID of the user record should be %d", newUserID)
|
||||
}
|
||||
if user.Name != "Sam" {
|
||||
t.Error("The user should be named Sam")
|
||||
}
|
||||
expectIntToBeX(t, user.Group, 5, "Sam should be in group 5")
|
||||
|
||||
if hasCache {
|
||||
expectIntToBeX(t, ucache.Length(), 1, "User cache length should be 1, not %d")
|
||||
user, err = ucache.CacheGet(newUserID)
|
||||
recordMustExist(t, err, fmt.Sprintf("Couldn't find UID #%d in the cache", newUserID))
|
||||
if user.ID != newUserID {
|
||||
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
|
||||
}
|
||||
}
|
||||
|
||||
count := users.GlobalCount()
|
||||
if count <= 0 {
|
||||
t.Error("The number of users should be bigger than zero")
|
||||
t.Error("count", count)
|
||||
err = user.Activate()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expectIntToBeX(t, user.Group, 5, "Sam should still be in group 5 in this copy")
|
||||
|
||||
// ? - What if we change the caching mechanism so it isn't hard purged and reloaded? We'll deal with that when we come to it, but for now, this is a sign of a cache bug
|
||||
if hasCache {
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
_, err = ucache.CacheGet(newUserID)
|
||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't be in the cache", newUserID))
|
||||
}
|
||||
|
||||
user, err = users.Get(newUserID)
|
||||
recordMustExist(t, err, fmt.Sprintf("Couldn't find UID #%d", newUserID))
|
||||
if user.ID != newUserID {
|
||||
t.Errorf("The UID of the user record should be %d", newUserID)
|
||||
}
|
||||
expectIntToBeX(t, user.Group, config.DefaultGroup, "Sam should be in group "+strconv.Itoa(config.DefaultGroup))
|
||||
|
||||
// Permanent ban
|
||||
duration, _ := time.ParseDuration("0")
|
||||
|
||||
// TODO: Attempt a double ban, double activation, and double unban
|
||||
err = user.Ban(duration, 1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expectIntToBeX(t, user.Group, config.DefaultGroup, "Sam should still be in the default group in this copy")
|
||||
|
||||
if hasCache {
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
_, err = ucache.CacheGet(2)
|
||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't be in the cache", newUserID))
|
||||
}
|
||||
|
||||
user, err = users.Get(newUserID)
|
||||
recordMustExist(t, err, fmt.Sprintf("Couldn't find UID #%d", newUserID))
|
||||
if user.ID != newUserID {
|
||||
t.Errorf("The UID of the user record should be %d", newUserID)
|
||||
}
|
||||
expectIntToBeX(t, user.Group, banGroup, "Sam should be in group "+strconv.Itoa(banGroup))
|
||||
|
||||
// TODO: Do tests against the scheduled updates table and the task system to make sure the ban exists there and gets revoked when it should
|
||||
|
||||
err = user.Unban()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expectIntToBeX(t, user.Group, banGroup, "Sam should still be in the ban group in this copy")
|
||||
|
||||
if hasCache {
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
_, err = ucache.CacheGet(newUserID)
|
||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't be in the cache", newUserID))
|
||||
}
|
||||
|
||||
user, err = users.Get(newUserID)
|
||||
recordMustExist(t, err, fmt.Sprintf("Couldn't find UID #%d", newUserID))
|
||||
if user.ID != newUserID {
|
||||
t.Errorf("The UID of the user record should be %d", newUserID)
|
||||
}
|
||||
expectIntToBeX(t, user.Group, config.DefaultGroup, "Sam should be back in group "+strconv.Itoa(config.DefaultGroup))
|
||||
|
||||
err = user.Delete()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
expect(t, !users.Exists(newUserID), fmt.Sprintf("UID #%d should not longer exist", newUserID))
|
||||
|
||||
if hasCache {
|
||||
expectIntToBeX(t, ucache.Length(), 0, "User cache length should be 0, not %d")
|
||||
_, err = ucache.CacheGet(newUserID)
|
||||
recordMustNotExist(t, err, fmt.Sprintf("UID #%d shouldn't be in the cache", newUserID))
|
||||
}
|
||||
|
||||
// TODO: Works for now but might cause a data race with the task system
|
||||
//ResetTables()
|
||||
}
|
||||
|
||||
func expectIntToBeX(t *testing.T, item int, expect int, errmsg string) {
|
||||
if item != expect {
|
||||
debug.PrintStack()
|
||||
t.Fatalf(errmsg, item)
|
||||
}
|
||||
}
|
||||
|
||||
func expect(t *testing.T, item bool, errmsg string) {
|
||||
if !item {
|
||||
debug.PrintStack()
|
||||
t.Fatalf(errmsg)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,11 +323,7 @@ func topicStoreTest(t *testing.T) {
|
|||
}
|
||||
|
||||
topic, err = topics.Get(1)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find TID #1")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find TID #1")
|
||||
|
||||
if topic.ID != 1 {
|
||||
t.Error("topic.ID does not match the requested TID. Got '" + strconv.Itoa(topic.ID) + "' instead.")
|
||||
|
@ -276,11 +379,7 @@ func TestForumStore(t *testing.T) {
|
|||
}
|
||||
|
||||
forum, err = fstore.Get(1)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find FID #1")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find FID #1")
|
||||
|
||||
if forum.ID != 1 {
|
||||
t.Error("forum.ID doesn't not match the requested FID. Got '" + strconv.Itoa(forum.ID) + "' instead.'")
|
||||
|
@ -290,11 +389,7 @@ func TestForumStore(t *testing.T) {
|
|||
}
|
||||
|
||||
forum, err = fstore.Get(2)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find FID #2")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find FID #1")
|
||||
|
||||
_ = forum
|
||||
|
||||
|
@ -332,12 +427,9 @@ func TestGroupStore(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// TODO: Refactor the group store to remove GID #0
|
||||
group, err = gstore.Get(0)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find GID #0")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find GID #0")
|
||||
|
||||
if group.ID != 0 {
|
||||
t.Error("group.ID doesn't not match the requested GID. Got '" + strconv.Itoa(group.ID) + "' instead.")
|
||||
|
@ -346,14 +438,8 @@ func TestGroupStore(t *testing.T) {
|
|||
t.Error("GID #0 is named '" + group.Name + "' and not 'Unknown'")
|
||||
}
|
||||
|
||||
// ? - What if they delete this group? x.x
|
||||
// ? - Maybe, pick a random group ID? That would take an extra query, and I'm not sure if I want to be rewriting custom test queries. Possibly, a Random() method on the GroupStore? Seems useless for normal use, it might have some merit for the TopicStore though
|
||||
group, err = gstore.Get(1)
|
||||
if err == ErrNoRows {
|
||||
t.Error("Couldn't find GID #1")
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recordMustExist(t, err, "Couldn't find GID #1")
|
||||
|
||||
if group.ID != 1 {
|
||||
t.Error("group.ID doesn't not match the requested GID. Got '" + strconv.Itoa(group.ID) + "' instead.'")
|
||||
|
|
60
mssql.go
60
mssql.go
|
@ -11,6 +11,7 @@ package main
|
|||
//import "time"
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"net/url"
|
||||
|
||||
"./query_gen/lib"
|
||||
|
@ -78,7 +79,62 @@ func initMSSQL() (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO: Add the custom queries
|
||||
setter, ok := qgen.Builder.GetAdapter().(qgen.SetPrimaryKeys)
|
||||
if ok {
|
||||
setter.SetPrimaryKeys(dbTablePrimaryKeys)
|
||||
}
|
||||
|
||||
return nil
|
||||
// TODO: Is there a less noisy way of doing this for tests?
|
||||
log.Print("Preparing get_activity_feed_by_watcher statement.")
|
||||
getActivityFeedByWatcherStmt, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID FROM [activity_stream_matches] INNER JOIN [activity_stream] ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE [watcher] = ? ORDER BY activity_stream.asid ASC OFFSET 0 ROWS FETCH NEXT 8 ROWS ONLY")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing get_activity_count_by_watcher statement.")
|
||||
getActivityCountByWatcherStmt, err = db.Prepare("SELECT count(*) FROM [activity_stream_matches] INNER JOIN [activity_stream] ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE [watcher] = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing todays_post_count statement.")
|
||||
todaysPostCountStmt, err = db.Prepare("select count(*) from replies where createdAt >= DATEADD(DAY, -1, GETUTCDATE())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing todays_topic_count statement.")
|
||||
todaysTopicCountStmt, err = db.Prepare("select count(*) from topics where createdAt >= DATEADD(DAY, -1, GETUTCDATE())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing todays_report_count statement.")
|
||||
todaysReportCountStmt, err = db.Prepare("select count(*) from topics where createdAt >= DATEADD(DAY, -1, GETUTCDATE()) and parentID = 1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing todays_newuser_count statement.")
|
||||
todaysNewUserCountStmt, err = db.Prepare("select count(*) from users where createdAt >= DATEADD(DAY, -1, GETUTCDATE())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ? - Why is this a custom query? Are we planning a union or something?
|
||||
log.Print("Preparing find_users_by_ip_users statement.")
|
||||
findUsersByIPUsersStmt, err = db.Prepare("select uid from users where last_ip = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing find_users_by_ip_topics statement.")
|
||||
findUsersByIPTopicsStmt, err = db.Prepare("select uid from users where uid in(select createdBy from topics where ipaddress = ?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing find_users_by_ip_replies statement.")
|
||||
findUsersByIPRepliesStmt, err = db.Prepare("select uid from users where uid in(select createdBy from replies where ipaddress = ?)")
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ func TestBBCodeRender(t *testing.T) {
|
|||
t.Error("Expected a number between 0 and 170141183460469231731687303715884105727")
|
||||
}
|
||||
|
||||
t.Log("Testing bbcode_regex_parse")
|
||||
/*t.Log("Testing bbcode_regex_parse")
|
||||
for _, item := range msgList {
|
||||
t.Log("Testing string '" + item.Msg + "'")
|
||||
res = bbcodeRegexParse(item.Msg)
|
||||
|
@ -188,7 +188,7 @@ func TestBBCodeRender(t *testing.T) {
|
|||
t.Error("Bad output:", "'"+res+"'")
|
||||
t.Error("Expected:", item.Expects)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
func TestMarkdownRender(t *testing.T) {
|
||||
|
|
|
@ -210,22 +210,22 @@ $(document).ready(function(){
|
|||
$(".hide_on_edit").show();
|
||||
$(".show_on_edit").hide();
|
||||
|
||||
var topic_name_input = $('.topic_name_input').val();
|
||||
var topic_status_input = $('.topic_status_input').val();
|
||||
var topic_content_input = $('.topic_content_input').val();
|
||||
var form_action = this.form.getAttribute("action");
|
||||
//console.log("New Topic Name: " + topic_name_input);
|
||||
//console.log("New Topic Status: " + topic_status_input);
|
||||
//console.log("New Topic Content: " + topic_content_input);
|
||||
//console.log("Form Action: " + form_action);
|
||||
let topicNameInput = $('.topic_name_input').val();
|
||||
let topicStatusInput = $('.topic_status_input').val();
|
||||
let topicContentInput = $('.topic_content_input').val();
|
||||
let formAction = this.form.getAttribute("action");
|
||||
//console.log("New Topic Name: " + topicNameInput);
|
||||
//console.log("New Topic Status: " + topicStatusInput);
|
||||
//console.log("New Topic Content: " + topicContentInput);
|
||||
//console.log("Form Action: " + formAction);
|
||||
$.ajax({
|
||||
url: form_action,
|
||||
url: formAction,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: {
|
||||
topic_name: topic_name_input,
|
||||
topic_status: topic_status_input,
|
||||
topic_content: topic_content_input,
|
||||
topic_name: topicNameInput,
|
||||
topic_status: topicStatusInput,
|
||||
topic_content: topicContentInput,
|
||||
topic_js: 1
|
||||
}
|
||||
});
|
||||
|
@ -234,28 +234,27 @@ $(document).ready(function(){
|
|||
$(".delete_item").click(function(event)
|
||||
{
|
||||
post_link(event);
|
||||
var block = $(this).closest('.deletable_block');
|
||||
block.remove();
|
||||
$(this).closest('.deletable_block').remove();
|
||||
});
|
||||
|
||||
$(".edit_item").click(function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
var block_parent = $(this).closest('.editable_parent');
|
||||
var block = block_parent.find('.editable_block').eq(0);
|
||||
let blockParent = $(this).closest('.editable_parent');
|
||||
let block = blockParent.find('.editable_block').eq(0);
|
||||
block.html("<textarea style='width: 99%;' name='edit_item'>" + block.html() + "</textarea><br /><a href='" + $(this).closest('a').attr("href") + "'><button class='submit_edit' type='submit'>Update</button></a>");
|
||||
|
||||
$(".submit_edit").click(function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
var block_parent = $(this).closest('.editable_parent');
|
||||
var block = block_parent.find('.editable_block').eq(0);
|
||||
var newContent = block.find('textarea').eq(0).val();
|
||||
let blockParent = $(this).closest('.editable_parent');
|
||||
let block = blockParent.find('.editable_block').eq(0);
|
||||
let newContent = block.find('textarea').eq(0).val();
|
||||
block.html(newContent);
|
||||
|
||||
var form_action = $(this).closest('a').attr("href");
|
||||
var formAction = $(this).closest('a').attr("href");
|
||||
//console.log("Form Action: " + form_action);
|
||||
$.ajax({ url: form_action, type: "POST", dataType: "json", data: { isJs: "1", edit_item: newContent }
|
||||
$.ajax({ url: formAction, type: "POST", dataType: "json", data: { isJs: "1", edit_item: newContent }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -263,22 +262,22 @@ $(document).ready(function(){
|
|||
$(".edit_field").click(function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
var block_parent = $(this).closest('.editable_parent');
|
||||
var block = block_parent.find('.editable_block').eq(0);
|
||||
let blockParent = $(this).closest('.editable_parent');
|
||||
let block = blockParent.find('.editable_block').eq(0);
|
||||
block.html("<input name='edit_field' value='" + block.text() + "' type='text'/><a href='" + $(this).closest('a').attr("href") + "'><button class='submit_edit' type='submit'>Update</button></a>");
|
||||
|
||||
$(".submit_edit").click(function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
var block_parent = $(this).closest('.editable_parent');
|
||||
var block = block_parent.find('.editable_block').eq(0);
|
||||
var newContent = block.find('input').eq(0).val();
|
||||
let blockParent = $(this).closest('.editable_parent');
|
||||
let block = blockParent.find('.editable_block').eq(0);
|
||||
let newContent = block.find('input').eq(0).val();
|
||||
block.html(newContent);
|
||||
|
||||
var form_action = $(this).closest('a').attr("href");
|
||||
//console.log("Form Action: " + form_action);
|
||||
let formAction = $(this).closest('a').attr("href");
|
||||
//console.log("Form Action: " + formAction);
|
||||
$.ajax({
|
||||
url: form_action + "?session=" + session,
|
||||
url: formAction + "?session=" + session,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: {isJs: "1",edit_item: newContent}
|
||||
|
|
|
@ -7,12 +7,11 @@ import "database/sql"
|
|||
var Builder *builder
|
||||
|
||||
func init() {
|
||||
Builder = &builder{conn:nil}
|
||||
Builder = &builder{conn: nil}
|
||||
}
|
||||
|
||||
// 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
|
||||
adapter DB_Adapter
|
||||
}
|
||||
|
@ -30,6 +29,10 @@ func (build *builder) SetAdapter(name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (build *builder) GetAdapter() DB_Adapter {
|
||||
return build.adapter
|
||||
}
|
||||
|
||||
func (build *builder) SimpleSelect(table string, columns string, where string, orderby string, limit string) (stmt *sql.Stmt, err error) {
|
||||
res, err := build.adapter.SimpleSelect("_builder", table, columns, where, orderby, limit)
|
||||
if err != nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ type DB_Install_Instruction struct {
|
|||
type installer struct {
|
||||
adapter DB_Adapter
|
||||
instructions []DB_Install_Instruction
|
||||
plugins []QueryPlugin
|
||||
}
|
||||
|
||||
func (install *installer) SetAdapter(name string) error {
|
||||
|
@ -35,20 +36,48 @@ func (install *installer) SetAdapterInstance(adapter DB_Adapter) {
|
|||
install.instructions = []DB_Install_Instruction{}
|
||||
}
|
||||
|
||||
func (install *installer) RegisterPlugin(plugin QueryPlugin) {
|
||||
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 {
|
||||
for _, plugin := range install.plugins {
|
||||
err := plugin.Hook("CreateTableStart", table, charset, collation, columns, keys)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
res, err := install.adapter.CreateTable("_installer", table, charset, collation, columns, keys)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, plugin := range install.plugins {
|
||||
err := plugin.Hook("CreateTableAfter", table, charset, collation, columns, keys, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
install.instructions = append(install.instructions, DB_Install_Instruction{table, res, "create-table"})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (install *installer) SimpleInsert(table string, columns string, fields string) error {
|
||||
for _, plugin := range install.plugins {
|
||||
err := plugin.Hook("SimpleInsertStart", table, columns, fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
res, err := install.adapter.SimpleInsert("_installer", table, columns, fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, plugin := range install.plugins {
|
||||
err := plugin.Hook("SimpleInsertAfter", table, columns, fields, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
install.instructions = append(install.instructions, DB_Install_Instruction{table, res, "insert"})
|
||||
return nil
|
||||
}
|
||||
|
@ -66,5 +95,18 @@ func (install *installer) Write() error {
|
|||
inserts += instr.Contents + ";\n"
|
||||
}
|
||||
}
|
||||
return writeFile("./schema/"+install.adapter.GetName()+"/inserts.sql", inserts)
|
||||
|
||||
err := writeFile("./schema/"+install.adapter.GetName()+"/inserts.sql", inserts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, plugin := range install.plugins {
|
||||
err := plugin.Write()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -149,6 +149,7 @@ func (adapter *Mysql_Adapter) SimpleInsert(name string, table string, columns st
|
|||
return querystr + ")", nil
|
||||
}
|
||||
|
||||
// ! DEPRECATED
|
||||
func (adapter *Mysql_Adapter) SimpleReplace(name string, table string, columns string, fields string) (string, error) {
|
||||
if name == "" {
|
||||
return "", errors.New("You need a name for this statement")
|
||||
|
@ -186,6 +187,53 @@ func (adapter *Mysql_Adapter) SimpleReplace(name string, table string, columns s
|
|||
return querystr + ")", nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) SimpleUpsert(name string, table string, columns string, fields string, where string) (string, error) {
|
||||
if name == "" {
|
||||
return "", errors.New("You need a name for this statement")
|
||||
}
|
||||
if table == "" {
|
||||
return "", errors.New("You need a name for this table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return "", errors.New("No columns found for SimpleInsert")
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return "", errors.New("No input data found for SimpleInsert")
|
||||
}
|
||||
if where == "" {
|
||||
return "", errors.New("You need a where for this upsert")
|
||||
}
|
||||
|
||||
var querystr = "INSERT INTO `" + table + "`("
|
||||
var parsedFields = processFields(fields)
|
||||
|
||||
var insertColumns string
|
||||
var insertValues string
|
||||
var setBit = ") ON DUPLICATE KEY UPDATE "
|
||||
|
||||
for columnID, column := range processColumns(columns) {
|
||||
field := parsedFields[columnID]
|
||||
if column.Type == "function" {
|
||||
insertColumns += column.Left + ","
|
||||
insertValues += field.Name + ","
|
||||
setBit += column.Left + " = " + field.Name + " AND "
|
||||
} else {
|
||||
insertColumns += "`" + column.Left + "`,"
|
||||
insertValues += field.Name + ","
|
||||
setBit += "`" + column.Left + "` = " + field.Name + " AND "
|
||||
}
|
||||
}
|
||||
insertColumns = insertColumns[0 : len(insertColumns)-1]
|
||||
insertValues = insertValues[0 : len(insertValues)-1]
|
||||
insertColumns += ") VALUES (" + insertValues
|
||||
setBit = setBit[0 : len(setBit)-5]
|
||||
|
||||
querystr += insertColumns + setBit
|
||||
|
||||
adapter.pushStatement(name, "upsert", querystr)
|
||||
return querystr, nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) SimpleUpdate(name string, table string, set string, where string) (string, error) {
|
||||
if name == "" {
|
||||
return "", errors.New("You need a name for this statement")
|
||||
|
@ -212,7 +260,6 @@ func (adapter *Mysql_Adapter) SimpleUpdate(name string, table string, set string
|
|||
}
|
||||
querystr += ","
|
||||
}
|
||||
|
||||
// Remove the trailing comma
|
||||
querystr = querystr[0 : len(querystr)-1]
|
||||
|
||||
|
@ -826,8 +873,17 @@ func (adapter *Mysql_Adapter) Write() error {
|
|||
continue
|
||||
}
|
||||
stmt := adapter.Buffer[name]
|
||||
// TODO: Add support for create-table? Table creation might be a little complex for Go to do outside a SQL file :(
|
||||
if stmt.Type != "create-table" {
|
||||
// ? - Table creation might be a little complex for Go to do outside a SQL file :(
|
||||
if stmt.Type == "upsert" {
|
||||
stmts += "var " + name + "Stmt *qgen.MySQLUpsertCallback\n"
|
||||
body += `
|
||||
log.Print("Preparing ` + name + ` statement.")
|
||||
` + name + `Stmt, err = qgen.PrepareMySQLUpsertCallback(db, "` + stmt.Contents + `")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
`
|
||||
} else if stmt.Type != "create-table" {
|
||||
stmts += "var " + name + "Stmt *sql.Stmt\n"
|
||||
body += `
|
||||
log.Print("Preparing ` + name + ` statement.")
|
||||
|
@ -847,6 +903,7 @@ package main
|
|||
|
||||
import "log"
|
||||
import "database/sql"
|
||||
import "./query_gen/lib"
|
||||
|
||||
// nolint
|
||||
` + stmts + `
|
||||
|
|
|
@ -128,6 +128,23 @@ func (adapter *Pgsql_Adapter) SimpleReplace(name string, table string, columns s
|
|||
return "", nil
|
||||
}
|
||||
|
||||
// TODO: Implement this
|
||||
func (adapter *Pgsql_Adapter) SimpleUpsert(name string, table string, columns string, fields string, where string) (string, error) {
|
||||
if name == "" {
|
||||
return "", errors.New("You need a name for this statement")
|
||||
}
|
||||
if table == "" {
|
||||
return "", errors.New("You need a name for this table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return "", errors.New("No columns found for SimpleInsert")
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return "", errors.New("No input data found for SimpleInsert")
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// TODO: Implemented, but we need CreateTable and a better installer to *test* it
|
||||
func (adapter *Pgsql_Adapter) SimpleUpdate(name string, table string, set string, where string) (string, error) {
|
||||
if name == "" {
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* WIP Under Construction */
|
||||
package qgen
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var DB_Registry []DB_Adapter
|
||||
var No_Adapter = errors.New("This adapter doesn't exist")
|
||||
var ErrNoAdapter = errors.New("This adapter doesn't exist")
|
||||
|
||||
type DB_Table_Column struct {
|
||||
Name string
|
||||
|
@ -97,7 +100,12 @@ type DB_Adapter interface {
|
|||
GetName() string
|
||||
CreateTable(name string, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (string, error)
|
||||
SimpleInsert(name string, table string, columns string, fields string) (string, error)
|
||||
|
||||
// ! DEPRECATED
|
||||
SimpleReplace(name string, table string, columns string, fields string) (string, error)
|
||||
|
||||
// ! NOTE: MySQL doesn't support upserts properly, asides from for keys, so this is just a less destructive replace atm
|
||||
SimpleUpsert(name string, table string, columns string, fields string, where string) (string, error)
|
||||
SimpleUpdate(name string, table string, set string, where string) (string, error)
|
||||
SimpleDelete(name string, table string, where string) (string, error)
|
||||
Purge(name string, table string) (string, error)
|
||||
|
@ -119,5 +127,27 @@ func GetAdapter(name string) (adap DB_Adapter, err error) {
|
|||
return adapter, nil
|
||||
}
|
||||
}
|
||||
return adap, No_Adapter
|
||||
return adap, ErrNoAdapter
|
||||
}
|
||||
|
||||
type QueryPlugin interface {
|
||||
Hook(name string, args ...interface{}) error
|
||||
Write() error
|
||||
}
|
||||
|
||||
type MySQLUpsertCallback struct {
|
||||
stmt *sql.Stmt
|
||||
}
|
||||
|
||||
func (double *MySQLUpsertCallback) Exec(args ...interface{}) (res sql.Result, err error) {
|
||||
if len(args) < 2 {
|
||||
return res, errors.New("Need two or more arguments")
|
||||
}
|
||||
args = args[:len(args)-1]
|
||||
return double.stmt.Exec(append(args, args...)...)
|
||||
}
|
||||
|
||||
func PrepareMySQLUpsertCallback(db *sql.DB, query string) (*MySQLUpsertCallback, error) {
|
||||
stmt, err := db.Prepare(query)
|
||||
return &MySQLUpsertCallback{stmt}, err
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
package qgen
|
||||
|
||||
//import "fmt"
|
||||
import "strings"
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func processColumns(colstr string) (columns []DB_Column) {
|
||||
if colstr == "" {
|
||||
|
@ -46,6 +48,7 @@ func processColumns(colstr string) (columns []DB_Column) {
|
|||
return columns
|
||||
}
|
||||
|
||||
// TODO: Allow order by statements without a direction
|
||||
func processOrderby(orderstr string) (order []DB_Order) {
|
||||
if orderstr == "" {
|
||||
return order
|
||||
|
|
|
@ -1,83 +1,116 @@
|
|||
/* WIP Under Construction */
|
||||
package main
|
||||
|
||||
import "log"
|
||||
import "./lib"
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
|
||||
"./lib"
|
||||
)
|
||||
|
||||
// TODO: Make sure all the errors in this file propagate upwards properly
|
||||
func main() {
|
||||
// Capture panics instead of closing the window at a superhuman speed before the user can read the message on Windows
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r != nil {
|
||||
fmt.Println(r)
|
||||
debug.PrintStack()
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
log.Println("Running the query generator")
|
||||
for _, adapter := range qgen.DB_Registry {
|
||||
log.Println("Building the queries for the " + adapter.GetName() + " adapter")
|
||||
qgen.Install.SetAdapterInstance(adapter)
|
||||
write_statements(adapter)
|
||||
qgen.Install.Write()
|
||||
adapter.Write()
|
||||
qgen.Install.RegisterPlugin(NewPrimaryKeySpitter()) // TODO: Do we really need to fill the spitter for every adapter?
|
||||
|
||||
err := writeStatements(adapter)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
err = qgen.Install.Write()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
err = adapter.Write()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_statements(adapter qgen.DB_Adapter) error {
|
||||
err := create_tables(adapter)
|
||||
func writeStatements(adapter qgen.DB_Adapter) error {
|
||||
err := createTables(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = seed_tables(adapter)
|
||||
err = seedTables(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_selects(adapter)
|
||||
err = writeSelects(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_left_joins(adapter)
|
||||
err = writeLeftJoins(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_inner_joins(adapter)
|
||||
err = writeInnerJoins(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_inserts(adapter)
|
||||
err = writeInserts(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_replaces(adapter)
|
||||
err = writeReplaces(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_updates(adapter)
|
||||
err = writeUpserts(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_deletes(adapter)
|
||||
err = writeUpdates(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_simple_counts(adapter)
|
||||
err = writeDeletes(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_insert_selects(adapter)
|
||||
err = writeSimpleCounts(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_insert_left_joins(adapter)
|
||||
err = writeInsertSelects(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = write_insert_inner_joins(adapter)
|
||||
err = writeInsertLeftJoins(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeInsertInnerJoins(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -85,368 +118,7 @@ func write_statements(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func create_tables(adapter qgen.DB_Adapter) error {
|
||||
qgen.Install.CreateTable("users", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"password", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"salt", "varchar", 80, false, false, "''"},
|
||||
qgen.DB_Table_Column{"group", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"is_super_admin", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastActiveAt", "datetime", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"session", "varchar", 200, false, false, "''"},
|
||||
qgen.DB_Table_Column{"last_ip", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
qgen.DB_Table_Column{"email", "varchar", 200, false, false, "''"},
|
||||
qgen.DB_Table_Column{"avatar", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"message", "text", 0, false, false, "''"},
|
||||
qgen.DB_Table_Column{"url_prefix", "varchar", 20, false, false, "''"},
|
||||
qgen.DB_Table_Column{"url_name", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"level", "smallint", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"score", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"posts", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"bigposts", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"megaposts", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"topics", "int", 0, false, false, "0"},
|
||||
//qgen.DB_Table_Column{"penalty_count","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.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uid", "primary"},
|
||||
qgen.DB_Table_Key{"name", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("users_groups", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"gid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"permissions", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"plugin_perms", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"is_mod", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"is_admin", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"is_banned", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"tag", "varchar", 50, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"gid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
// What should we do about global penalties? Put them on the users table for speed? Or keep them here?
|
||||
// Should we add IP Penalties? No, that's a stupid idea, just implement IP Bans properly. What about shadowbans?
|
||||
// TODO: Perm overrides
|
||||
// TODO: Add a mod-queue and other basic auto-mod features. This is needed for awaiting activation and the mod_queue penalty flag
|
||||
// TODO: Add a penalty type where a user is stopped from creating plugin_socialgroups social groups
|
||||
// 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.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uid","int",0,false,false,""},
|
||||
qgen.DB_Table_Column{"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.DB_Table_Column{"overrides","text",0,false,false,"{}"},
|
||||
|
||||
qgen.DB_Table_Column{"mod_queue","boolean",0,false,false,"0"},
|
||||
qgen.DB_Table_Column{"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?
|
||||
|
||||
// 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.DB_Table_Column{"topics_per_hour","int",0,false,false,"0"},
|
||||
//qgen.DB_Table_Column{"posts_count","int",0,false,false,"0"},
|
||||
//qgen.DB_Table_Column{"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.DB_Table_Column{"issued_by","int",0,false,false,""},
|
||||
qgen.DB_Table_Column{"issued_at","createdAt",0,false,false,""},
|
||||
qgen.DB_Table_Column{"expires_at","datetime",0,false,false,""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)*/
|
||||
|
||||
qgen.Install.CreateTable("users_groups_scheduler", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"set_group", "int", 0, false, false, ""},
|
||||
|
||||
qgen.DB_Table_Column{"issued_by", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"issued_at", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"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.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("emails", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"email", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"validated", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"token", "varchar", 200, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("forums", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"fid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"desc", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "1"},
|
||||
qgen.DB_Table_Column{"topicCount", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"preset", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"parentID", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"parentType", "varchar", 50, false, false, "''"},
|
||||
qgen.DB_Table_Column{"lastTopicID", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"lastReplyerID", "int", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"fid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("forums_permissions", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"fid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"gid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"preset", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"permissions", "text", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
// TODO: Test to see that the compound primary key works
|
||||
qgen.DB_Table_Key{"fid,gid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("topics", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"tid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"title", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastReplyAt", "datetime", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastReplyBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"is_closed", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"sticky", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"parentID", "int", 0, false, false, "2"},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
qgen.DB_Table_Column{"postCount", "int", 0, false, false, "1"},
|
||||
qgen.DB_Table_Column{"likeCount", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"words", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"css_class", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"data", "varchar", 200, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"tid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("replies", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"rid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"tid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEdit", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEditBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastUpdated", "datetime", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
qgen.DB_Table_Column{"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.DB_Table_Column{"actionType", "varchar", 20, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"rid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("attachments", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"attachID", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"sectionID", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"sectionTable", "varchar", 200, false, false, "forums"},
|
||||
qgen.DB_Table_Column{"originID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"originTable", "varchar", 200, false, false, "replies"},
|
||||
qgen.DB_Table_Column{"uploadedBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"path", "varchar", 200, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"attachID", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("revisions", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"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.DB_Table_Column{"contentID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"contentType", "varchar", 100, false, false, "replies"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("users_replies", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"rid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEdit", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEditBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"rid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("likes", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"weight", "tinyint", 0, false, false, "1"},
|
||||
qgen.DB_Table_Column{"targetItem", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"targetType", "varchar", 50, false, false, "replies"},
|
||||
qgen.DB_Table_Column{"sentBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"recalc", "tinyint", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("activity_stream_matches", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"watcher", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"asid", "int", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("activity_stream", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"asid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"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.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.DB_Table_Column{"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.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"asid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("activity_subscriptions", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"user", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"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.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.DB_Table_Key{},
|
||||
)
|
||||
|
||||
/* 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.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"name", "varchar", 180, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "varchar", 250, false, false, ""},
|
||||
qgen.DB_Table_Column{"type", "varchar", 50, false, false, ""},
|
||||
qgen.DB_Table_Column{"constraints", "varchar", 200, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"name", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("word_filters", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"wfid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"find", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"replacement", "varchar", 200, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"wfid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("plugins", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uname", "varchar", 180, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"installed", "boolean", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uname", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("themes", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uname", "varchar", 180, false, false, ""},
|
||||
qgen.DB_Table_Column{"default", "boolean", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uname", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("widgets", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"position", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"side", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"type", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"location", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"data", "text", 0, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("moderation_logs", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"action", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementType", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"actorID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"doneAt", "datetime", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("administration_logs", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"action", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementType", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"actorID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"doneAt", "datetime", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("sync", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"last_update", "datetime", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func seed_tables(adapter qgen.DB_Adapter) error {
|
||||
func seedTables(adapter qgen.DB_Adapter) error {
|
||||
qgen.Install.SimpleInsert("sync", "last_update", "UTC_TIMESTAMP()")
|
||||
|
||||
qgen.Install.SimpleInsert("settings", "name, content, type", "'url_tags','1','bool'")
|
||||
|
@ -547,8 +219,7 @@ func seed_tables(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_selects(adapter qgen.DB_Adapter) error {
|
||||
func writeSelects(adapter qgen.DB_Adapter) error {
|
||||
// url_prefix and url_name will be removed from this query in a later commit
|
||||
adapter.SimpleSelect("getUser", "users", "name, group, is_super_admin, avatar, message, url_prefix, url_name, level", "uid = ?", "", "")
|
||||
|
||||
|
@ -586,7 +257,7 @@ func write_selects(adapter qgen.DB_Adapter) error {
|
|||
|
||||
adapter.SimpleSelect("getUsers", "users", "uid, name, group, active, is_super_admin, avatar", "", "", "")
|
||||
|
||||
adapter.SimpleSelect("getUsersOffset", "users", "uid, name, group, active, is_super_admin, avatar", "", "", "?,?")
|
||||
adapter.SimpleSelect("getUsersOffset", "users", "uid, name, group, active, is_super_admin, avatar", "", "uid ASC", "?,?")
|
||||
|
||||
adapter.SimpleSelect("getWordFilters", "word_filters", "wfid, find, replacement", "", "", "")
|
||||
|
||||
|
@ -594,7 +265,7 @@ func write_selects(adapter qgen.DB_Adapter) error {
|
|||
|
||||
adapter.SimpleSelect("getModlogs", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "", "")
|
||||
|
||||
adapter.SimpleSelect("getModlogsOffset", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "", "?,?")
|
||||
adapter.SimpleSelect("getModlogsOffset", "moderation_logs", "action, elementID, elementType, ipaddress, actorID, doneAt", "", "doneAt DESC", "?,?")
|
||||
|
||||
adapter.SimpleSelect("getReplyTID", "replies", "tid", "rid = ?", "", "")
|
||||
|
||||
|
@ -629,9 +300,8 @@ func write_selects(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_left_joins(adapter qgen.DB_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 = ?", "", "?,?")
|
||||
func writeLeftJoins(adapter qgen.DB_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("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", "")
|
||||
|
||||
|
@ -648,22 +318,23 @@ func write_left_joins(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_inner_joins(adapter qgen.DB_Adapter) error {
|
||||
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 = ?", "", "")
|
||||
func writeInnerJoins(adapter qgen.DB_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 = ?", "", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_inserts(adapter qgen.DB_Adapter) error {
|
||||
func writeInserts(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleInsert("createTopic", "topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?")
|
||||
|
||||
adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, 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("createReply", "replies", "tid, content, parsed_content, createdAt, ipaddress, words, createdBy", "?,?,?,UTC_TIMESTAMP(),?,?,?")
|
||||
adapter.SimpleInsert("createReply", "replies", "tid, content, parsed_content, createdAt, lastUpdated, ipaddress, words, createdBy", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?")
|
||||
|
||||
adapter.SimpleInsert("createActionReply", "replies", "tid, actionType, ipaddress, createdBy", "?,?,?,?")
|
||||
adapter.SimpleInsert("createActionReply", "replies", "tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''")
|
||||
|
||||
adapter.SimpleInsert("createLike", "likes", "weight, targetItem, targetType, sentBy", "?,?,?,?")
|
||||
|
||||
|
@ -698,17 +369,25 @@ func write_inserts(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_replaces(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleReplace("addForumPermsToGroup", "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?")
|
||||
func writeReplaces(adapter qgen.DB_Adapter) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
adapter.SimpleReplace("replaceScheduleGroup", "users_groups_scheduler", "uid, set_group, issued_by, issued_at, revert_at, temporary", "?,?,?,UTC_TIMESTAMP(),?,?")
|
||||
func writeUpserts(adapter qgen.DB_Adapter) (err error) {
|
||||
_, err = adapter.SimpleUpsert("addForumPermsToGroup", "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?", "gid = ? AND fid = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = adapter.SimpleUpsert("replaceScheduleGroup", "users_groups_scheduler", "uid, set_group, issued_by, issued_at, revert_at, temporary", "?,?,?,UTC_TIMESTAMP(),?,?", "uid = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_updates(adapter qgen.DB_Adapter) error {
|
||||
func writeUpdates(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleUpdate("addRepliesToTopic", "topics", "postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()", "tid = ?")
|
||||
|
||||
adapter.SimpleUpdate("removeRepliesFromTopic", "topics", "postCount = postCount - ?", "tid = ?")
|
||||
|
@ -794,8 +473,9 @@ func write_updates(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_deletes(adapter qgen.DB_Adapter) error {
|
||||
func writeDeletes(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleDelete("deleteUser", "users", "uid = ?")
|
||||
|
||||
adapter.SimpleDelete("deleteReply", "replies", "rid = ?")
|
||||
|
||||
adapter.SimpleDelete("deleteProfileReply", "users_replies", "rid = ?")
|
||||
|
@ -810,8 +490,7 @@ func write_deletes(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_simple_counts(adapter qgen.DB_Adapter) error {
|
||||
func writeSimpleCounts(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleCount("reportExists", "topics", "data = ? AND data != '' AND parentID = 1", "")
|
||||
|
||||
adapter.SimpleCount("groupCount", "users_groups", "", "")
|
||||
|
@ -821,8 +500,7 @@ func write_simple_counts(adapter qgen.DB_Adapter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_insert_selects(adapter qgen.DB_Adapter) error {
|
||||
func writeInsertSelects(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleInsertSelect("addForumPermsToForumAdmins",
|
||||
qgen.DB_Insert{"forums_permissions", "gid, fid, preset, permissions", ""},
|
||||
qgen.DB_Select{"users_groups", "gid, ? AS fid, ? AS preset, ? AS permissions", "is_admin = 1", "", ""},
|
||||
|
@ -842,12 +520,11 @@ func write_insert_selects(adapter qgen.DB_Adapter) error {
|
|||
}
|
||||
|
||||
// nolint
|
||||
func write_insert_left_joins(adapter qgen.DB_Adapter) error {
|
||||
func writeInsertLeftJoins(adapter qgen.DB_Adapter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func write_insert_inner_joins(adapter qgen.DB_Adapter) error {
|
||||
func writeInsertInnerJoins(adapter qgen.DB_Adapter) error {
|
||||
adapter.SimpleInsertInnerJoin("notifyWatchers",
|
||||
qgen.DB_Insert{"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 = ?", "", ""},
|
||||
|
@ -855,3 +532,19 @@ func write_insert_inner_joins(adapter qgen.DB_Adapter) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeFile(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
|
||||
}
|
||||
err = f.Sync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package main
|
||||
|
||||
import "strings"
|
||||
import "./lib"
|
||||
|
||||
type PrimaryKeySpitter struct {
|
||||
keys map[string]string
|
||||
}
|
||||
|
||||
func NewPrimaryKeySpitter() *PrimaryKeySpitter {
|
||||
return &PrimaryKeySpitter{make(map[string]string)}
|
||||
}
|
||||
|
||||
func (spit *PrimaryKeySpitter) Hook(name string, args ...interface{}) error {
|
||||
if name == "CreateTableStart" {
|
||||
var found string
|
||||
for _, key := range args[4].([]qgen.DB_Table_Key) {
|
||||
if key.Type == "primary" {
|
||||
expl := strings.Split(key.Columns, ",")
|
||||
if len(expl) > 1 {
|
||||
continue
|
||||
}
|
||||
found = key.Columns
|
||||
}
|
||||
if found != "" {
|
||||
table := args[0].(string)
|
||||
spit.keys[table] = found
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (spit *PrimaryKeySpitter) Write() error {
|
||||
out := `// Generated by Gosora's Query Generator. DO NOT EDIT.
|
||||
package main
|
||||
|
||||
var dbTablePrimaryKeys = map[string]string{
|
||||
`
|
||||
for table, key := range spit.keys {
|
||||
out += "\t\"" + table + "\":\"" + key + "\",\n"
|
||||
}
|
||||
return writeFile("./gen_tables.go", out+"}\n")
|
||||
}
|
|
@ -0,0 +1,363 @@
|
|||
/* WIP Under Construction */
|
||||
package main
|
||||
|
||||
import "./lib"
|
||||
|
||||
func createTables(adapter qgen.DB_Adapter) error {
|
||||
qgen.Install.CreateTable("users", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"password", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"salt", "varchar", 80, false, false, "''"},
|
||||
qgen.DB_Table_Column{"group", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"is_super_admin", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastActiveAt", "datetime", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"session", "varchar", 200, false, false, "''"},
|
||||
qgen.DB_Table_Column{"last_ip", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
qgen.DB_Table_Column{"email", "varchar", 200, false, false, "''"},
|
||||
qgen.DB_Table_Column{"avatar", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"message", "text", 0, false, false, "''"},
|
||||
qgen.DB_Table_Column{"url_prefix", "varchar", 20, false, false, "''"},
|
||||
qgen.DB_Table_Column{"url_name", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"level", "smallint", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"score", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"posts", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"bigposts", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"megaposts", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"topics", "int", 0, false, false, "0"},
|
||||
//qgen.DB_Table_Column{"penalty_count","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.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uid", "primary"},
|
||||
qgen.DB_Table_Key{"name", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("users_groups", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"gid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"permissions", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"plugin_perms", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"is_mod", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"is_admin", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"is_banned", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"tag", "varchar", 50, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"gid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
// What should we do about global penalties? Put them on the users table for speed? Or keep them here?
|
||||
// Should we add IP Penalties? No, that's a stupid idea, just implement IP Bans properly. What about shadowbans?
|
||||
// TODO: Perm overrides
|
||||
// TODO: Add a mod-queue and other basic auto-mod features. This is needed for awaiting activation and the mod_queue penalty flag
|
||||
// TODO: Add a penalty type where a user is stopped from creating plugin_socialgroups social groups
|
||||
// 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.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uid","int",0,false,false,""},
|
||||
qgen.DB_Table_Column{"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.DB_Table_Column{"overrides","text",0,false,false,"{}"},
|
||||
|
||||
qgen.DB_Table_Column{"mod_queue","boolean",0,false,false,"0"},
|
||||
qgen.DB_Table_Column{"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?
|
||||
|
||||
// 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.DB_Table_Column{"topics_per_hour","int",0,false,false,"0"},
|
||||
//qgen.DB_Table_Column{"posts_count","int",0,false,false,"0"},
|
||||
//qgen.DB_Table_Column{"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.DB_Table_Column{"issued_by","int",0,false,false,""},
|
||||
qgen.DB_Table_Column{"issued_at","createdAt",0,false,false,""},
|
||||
qgen.DB_Table_Column{"expires_at","datetime",0,false,false,""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)*/
|
||||
|
||||
qgen.Install.CreateTable("users_groups_scheduler", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"set_group", "int", 0, false, false, ""},
|
||||
|
||||
qgen.DB_Table_Column{"issued_by", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"issued_at", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"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.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("emails", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"email", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"validated", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"token", "varchar", 200, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("forums", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"fid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"name", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"desc", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "1"},
|
||||
qgen.DB_Table_Column{"topicCount", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"preset", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"parentID", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"parentType", "varchar", 50, false, false, "''"},
|
||||
qgen.DB_Table_Column{"lastTopicID", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"lastReplyerID", "int", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"fid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("forums_permissions", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"fid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"gid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"preset", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"permissions", "text", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
// TODO: Test to see that the compound primary key works
|
||||
qgen.DB_Table_Key{"fid,gid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("topics", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"tid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"title", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastReplyAt", "datetime", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastReplyBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"is_closed", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"sticky", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"parentID", "int", 0, false, false, "2"},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
qgen.DB_Table_Column{"postCount", "int", 0, false, false, "1"},
|
||||
qgen.DB_Table_Column{"likeCount", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"words", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"css_class", "varchar", 100, false, false, "''"},
|
||||
qgen.DB_Table_Column{"data", "varchar", 200, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"tid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("replies", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"rid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"tid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEdit", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"lastEditBy", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"lastUpdated", "datetime", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
qgen.DB_Table_Column{"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.DB_Table_Column{"actionType", "varchar", 20, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"rid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("attachments", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"attachID", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"sectionID", "int", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"sectionTable", "varchar", 200, false, false, "forums"},
|
||||
qgen.DB_Table_Column{"originID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"originTable", "varchar", 200, false, false, "replies"},
|
||||
qgen.DB_Table_Column{"uploadedBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"path", "varchar", 200, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"attachID", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("revisions", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"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.DB_Table_Column{"contentID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"contentType", "varchar", 100, false, false, "replies"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("users_replies", "utf8mb4", "utf8mb4_general_ci",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"rid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"uid", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"parsed_content", "text", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdAt", "createdAt", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"createdBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEdit", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"lastEditBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, "0.0.0.0.0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"rid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("likes", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"weight", "tinyint", 0, false, false, "1"},
|
||||
qgen.DB_Table_Column{"targetItem", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"targetType", "varchar", 50, false, false, "replies"},
|
||||
qgen.DB_Table_Column{"sentBy", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"recalc", "tinyint", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("activity_stream_matches", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"watcher", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"asid", "int", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("activity_stream", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"asid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"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.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.DB_Table_Column{"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.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"asid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("activity_subscriptions", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"user", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"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.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.DB_Table_Key{},
|
||||
)
|
||||
|
||||
/* 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.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"name", "varchar", 180, false, false, ""},
|
||||
qgen.DB_Table_Column{"content", "varchar", 250, false, false, ""},
|
||||
qgen.DB_Table_Column{"type", "varchar", 50, false, false, ""},
|
||||
qgen.DB_Table_Column{"constraints", "varchar", 200, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"name", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("word_filters", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"wfid", "int", 0, false, true, ""},
|
||||
qgen.DB_Table_Column{"find", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"replacement", "varchar", 200, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"wfid", "primary"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("plugins", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uname", "varchar", 180, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"installed", "boolean", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uname", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("themes", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"uname", "varchar", 180, false, false, ""},
|
||||
qgen.DB_Table_Column{"default", "boolean", 0, false, false, "0"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{
|
||||
qgen.DB_Table_Key{"uname", "unique"},
|
||||
},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("widgets", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"position", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"side", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"type", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"active", "boolean", 0, false, false, "0"},
|
||||
qgen.DB_Table_Column{"location", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"data", "text", 0, false, false, "''"},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("moderation_logs", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"action", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementType", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"actorID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"doneAt", "datetime", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("administration_logs", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"action", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"elementType", "varchar", 100, false, false, ""},
|
||||
qgen.DB_Table_Column{"ipaddress", "varchar", 200, false, false, ""},
|
||||
qgen.DB_Table_Column{"actorID", "int", 0, false, false, ""},
|
||||
qgen.DB_Table_Column{"doneAt", "datetime", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
qgen.Install.CreateTable("sync", "", "",
|
||||
[]qgen.DB_Table_Column{
|
||||
qgen.DB_Table_Column{"last_update", "datetime", 0, false, false, ""},
|
||||
},
|
||||
[]qgen.DB_Table_Key{},
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -433,11 +433,7 @@ func routeForums(w http.ResponseWriter, r *http.Request, user User) {
|
|||
//topic, user := forum.GetLast()
|
||||
//if topic.ID != 0 && user.ID != 0 {
|
||||
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
|
||||
forum.LastTopicTime, err = relativeTimeFromString(forum.LastTopic.LastReplyAt)
|
||||
if err != nil {
|
||||
InternalError(err, w)
|
||||
return
|
||||
}
|
||||
forum.LastTopicTime = relativeTime(forum.LastTopic.LastReplyAt)
|
||||
} else {
|
||||
forum.LastTopicTime = ""
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [activity_stream];
|
||||
CREATE TABLE [activity_stream] (
|
||||
[asid] int not null IDENTITY,
|
||||
[actor] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [activity_stream_matches];
|
||||
CREATE TABLE [activity_stream_matches] (
|
||||
[watcher] int not null,
|
||||
[asid] int not null
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [activity_subscriptions];
|
||||
CREATE TABLE [activity_subscriptions] (
|
||||
[user] int not null,
|
||||
[targetID] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [administration_logs];
|
||||
CREATE TABLE [administration_logs] (
|
||||
[action] nvarchar (100) not null,
|
||||
[elementID] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [attachments];
|
||||
CREATE TABLE [attachments] (
|
||||
[attachID] int not null IDENTITY,
|
||||
[sectionID] int DEFAULT 0 not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [emails];
|
||||
CREATE TABLE [emails] (
|
||||
[email] nvarchar (200) not null,
|
||||
[uid] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [forums];
|
||||
CREATE TABLE [forums] (
|
||||
[fid] int not null IDENTITY,
|
||||
[name] nvarchar (100) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [forums_permissions];
|
||||
CREATE TABLE [forums_permissions] (
|
||||
[fid] int not null,
|
||||
[gid] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [likes];
|
||||
CREATE TABLE [likes] (
|
||||
[weight] tinyint DEFAULT 1 not null,
|
||||
[targetItem] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [moderation_logs];
|
||||
CREATE TABLE [moderation_logs] (
|
||||
[action] nvarchar (100) not null,
|
||||
[elementID] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [plugins];
|
||||
CREATE TABLE [plugins] (
|
||||
[uname] nvarchar (180) not null,
|
||||
[active] bit DEFAULT 0 not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [replies];
|
||||
CREATE TABLE [replies] (
|
||||
[rid] int not null IDENTITY,
|
||||
[tid] int not null,
|
||||
|
@ -6,8 +5,8 @@ CREATE TABLE [replies] (
|
|||
[parsed_content] nvarchar (MAX) not null,
|
||||
[createdAt] datetime not null,
|
||||
[createdBy] int not null,
|
||||
[lastEdit] int not null,
|
||||
[lastEditBy] int not null,
|
||||
[lastEdit] int DEFAULT 0 not null,
|
||||
[lastEditBy] int DEFAULT 0 not null,
|
||||
[lastUpdated] datetime not null,
|
||||
[ipaddress] nvarchar (200) DEFAULT '0.0.0.0.0' not null,
|
||||
[likeCount] int DEFAULT 0 not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [revisions];
|
||||
CREATE TABLE [revisions] (
|
||||
[index] int not null,
|
||||
[content] nvarchar (MAX) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [settings];
|
||||
CREATE TABLE [settings] (
|
||||
[name] nvarchar (180) not null,
|
||||
[content] nvarchar (250) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [sync];
|
||||
CREATE TABLE [sync] (
|
||||
[last_update] datetime not null
|
||||
);
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [themes];
|
||||
CREATE TABLE [themes] (
|
||||
[uname] nvarchar (180) not null,
|
||||
[default] bit DEFAULT 0 not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [topics];
|
||||
CREATE TABLE [topics] (
|
||||
[tid] int not null IDENTITY,
|
||||
[title] nvarchar (100) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [users];
|
||||
CREATE TABLE [users] (
|
||||
[uid] int not null IDENTITY,
|
||||
[name] nvarchar (100) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [users_groups];
|
||||
CREATE TABLE [users_groups] (
|
||||
[gid] int not null IDENTITY,
|
||||
[name] nvarchar (100) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [users_groups_scheduler];
|
||||
CREATE TABLE [users_groups_scheduler] (
|
||||
[uid] int not null,
|
||||
[set_group] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [users_replies];
|
||||
CREATE TABLE [users_replies] (
|
||||
[rid] int not null IDENTITY,
|
||||
[uid] int not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [widgets];
|
||||
CREATE TABLE [widgets] (
|
||||
[position] int not null,
|
||||
[side] nvarchar (100) not null,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
DROP TABLE IF EXISTS [word_filters];
|
||||
CREATE TABLE [word_filters] (
|
||||
[wfid] int not null IDENTITY,
|
||||
[find] nvarchar (200) not null,
|
||||
|
|
|
@ -5,8 +5,8 @@ CREATE TABLE `replies` (
|
|||
`parsed_content` text not null,
|
||||
`createdAt` datetime not null,
|
||||
`createdBy` int not null,
|
||||
`lastEdit` int not null,
|
||||
`lastEditBy` int not null,
|
||||
`lastEdit` int DEFAULT 0 not null,
|
||||
`lastEditBy` int DEFAULT 0 not null,
|
||||
`lastUpdated` datetime not null,
|
||||
`ipaddress` varchar(200) DEFAULT '0.0.0.0.0' not null,
|
||||
`likeCount` int DEFAULT 0 not null,
|
||||
|
|
|
@ -5,8 +5,8 @@ CREATE TABLE `replies` (
|
|||
`parsed_content` text not null,
|
||||
`createdAt` timestamp not null,
|
||||
`createdBy` int not null,
|
||||
`lastEdit` int not null,
|
||||
`lastEditBy` int not null,
|
||||
`lastEdit` int DEFAULT 0 not null,
|
||||
`lastEditBy` int DEFAULT 0 not null,
|
||||
`lastUpdated` timestamp not null,
|
||||
`ipaddress` varchar (200) DEFAULT '0.0.0.0.0' not null,
|
||||
`likeCount` int DEFAULT 0 not null,
|
||||
|
|
12
tasks.go
12
tasks.go
|
@ -6,7 +6,10 @@
|
|||
*/
|
||||
package main
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var lastSync time.Time
|
||||
|
||||
|
@ -28,12 +31,14 @@ func handleExpiredScheduledGroups() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = replaceScheduleGroupStmt.Exec(uid, 0, 0, time.Now(), false)
|
||||
_, err = replaceScheduleGroupStmt.Exec(uid, 0, 0, time.Now(), false, uid)
|
||||
if err != nil {
|
||||
log.Print("Unable to replace the scheduled group")
|
||||
return err
|
||||
}
|
||||
_, err = setTempGroupStmt.Exec(0, uid)
|
||||
if err != nil {
|
||||
log.Print("Unable to reset the tempgroup")
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
|
@ -54,16 +59,19 @@ func handleServerSync() error {
|
|||
// TODO: A more granular sync
|
||||
err = fstore.LoadForums()
|
||||
if err != nil {
|
||||
log.Print("Unable to reload the forums")
|
||||
return err
|
||||
}
|
||||
// TODO: Resync the groups
|
||||
// TODO: Resync the permissions
|
||||
err = LoadSettings()
|
||||
if err != nil {
|
||||
log.Print("Unable to reload the settings")
|
||||
return err
|
||||
}
|
||||
err = LoadWordFilters()
|
||||
if err != nil {
|
||||
log.Print("Unable to reload the word filters")
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ func compileTemplates() error {
|
|||
|
||||
log.Print("Compiling the templates")
|
||||
|
||||
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, "Date", "Date", 0, "", "127.0.0.1", 0, 1, "classname", "weird-data", buildProfileURL("fake-user", 62), "Fake User", config.DefaultGroup, "", 0, "", "", "", "", "", 58, false}
|
||||
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, "Date", time.Now(), "Date", 0, "", "127.0.0.1", 0, 1, "classname", "weird-data", buildProfileURL("fake-user", 62), "Fake User", config.DefaultGroup, "", 0, "", "", "", "", "", 58, false}
|
||||
var replyList []ReplyUser
|
||||
replyList = append(replyList, ReplyUser{0, 0, "Yo!", "Yo!", 0, "alice", "Alice", config.DefaultGroup, "", 0, 0, "", "", 0, "", "", "", "", 0, "127.0.0.1", false, 1, "", ""})
|
||||
|
||||
|
|
6
topic.go
6
topic.go
|
@ -25,7 +25,8 @@ type Topic struct {
|
|||
IsClosed bool
|
||||
Sticky bool
|
||||
CreatedAt string
|
||||
LastReplyAt string
|
||||
LastReplyAt time.Time
|
||||
RelativeLastReplyAt string
|
||||
//LastReplyBy int
|
||||
ParentID int
|
||||
Status string // Deprecated. Marked for removal.
|
||||
|
@ -45,7 +46,8 @@ type TopicUser struct {
|
|||
IsClosed bool
|
||||
Sticky bool
|
||||
CreatedAt string
|
||||
LastReplyAt string
|
||||
LastReplyAt time.Time
|
||||
RelativeLastReplyAt string
|
||||
//LastReplyBy int
|
||||
ParentID int
|
||||
Status string // Deprecated. Marked for removal.
|
||||
|
|
24
user.go
24
user.go
|
@ -15,6 +15,9 @@ import (
|
|||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// TODO: Replace any literals with this
|
||||
var banGroup = 4
|
||||
|
||||
var guestUser = User{ID: 0, Link: "#", Group: 6, Perms: GuestPerms}
|
||||
|
||||
//func(real_password string, password string, salt string) (err error)
|
||||
|
@ -59,7 +62,7 @@ type Email struct {
|
|||
}
|
||||
|
||||
func (user *User) Ban(duration time.Duration, issuedBy int) error {
|
||||
return user.ScheduleGroupUpdate(4, issuedBy, duration)
|
||||
return user.ScheduleGroupUpdate(banGroup, issuedBy, duration)
|
||||
}
|
||||
|
||||
func (user *User) Unban() error {
|
||||
|
@ -80,7 +83,7 @@ func (user *User) ScheduleGroupUpdate(gid int, issuedBy int, duration time.Durat
|
|||
}
|
||||
|
||||
revertAt := time.Now().Add(duration)
|
||||
_, err := replaceScheduleGroupStmt.Exec(user.ID, gid, issuedBy, revertAt, temporary)
|
||||
_, err := replaceScheduleGroupStmt.Exec(user.ID, gid, issuedBy, revertAt, temporary, user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -94,7 +97,7 @@ func (user *User) ScheduleGroupUpdate(gid int, issuedBy int, duration time.Durat
|
|||
|
||||
// TODO: Use a transaction to avoid race conditions
|
||||
func (user *User) RevertGroupUpdate() error {
|
||||
_, err := replaceScheduleGroupStmt.Exec(user.ID, 0, 0, time.Now(), false)
|
||||
_, err := replaceScheduleGroupStmt.Exec(user.ID, 0, 0, time.Now(), false, user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -121,6 +124,21 @@ func (user *User) Activate() (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO: Write tests for this
|
||||
// TODO: Delete this user's content too?
|
||||
// TODO: Expose this to the admin?
|
||||
func (user *User) Delete() error {
|
||||
_, err := deleteUserStmt.Exec(user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ucache, ok := users.(UserCache)
|
||||
if ok {
|
||||
ucache.CacheRemove(user.ID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (user *User) ChangeName(username string) (err error) {
|
||||
_, err = setUsernameStmt.Exec(username, user.ID)
|
||||
ucache, ok := users.(UserCache)
|
||||
|
|
|
@ -69,7 +69,7 @@ func NewMemoryUserStore(capacity int) *MemoryUserStore {
|
|||
|
||||
// Add an admin version of register_stmt with more flexibility?
|
||||
// create_account_stmt, err = db.Prepare("INSERT INTO
|
||||
registerStmt, err := qgen.Builder.SimpleInsert("users", "name, email, password, salt, group, is_super_admin, session, active, message", "?,?,?,?,?,0,'',?,''")
|
||||
registerStmt, err := qgen.Builder.SimpleInsert("users", "name, email, password, salt, group, is_super_admin, session, active, message, createdAt, lastActiveAt", "?,?,?,?,?,0,'',?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -289,7 +289,11 @@ func (mus *MemoryUserStore) Reload(id int) error {
|
|||
}
|
||||
|
||||
func (mus *MemoryUserStore) Exists(id int) bool {
|
||||
return mus.exists.QueryRow(id).Scan(&id) == nil
|
||||
err := mus.exists.QueryRow(id).Scan(&id)
|
||||
if err != nil && err != ErrNoRows {
|
||||
LogError(err)
|
||||
}
|
||||
return err != ErrNoRows
|
||||
}
|
||||
|
||||
func (mus *MemoryUserStore) CacheSet(item *User) error {
|
||||
|
@ -315,8 +319,8 @@ func (mus *MemoryUserStore) CacheAdd(item *User) error {
|
|||
}
|
||||
mus.Lock()
|
||||
mus.items[item.ID] = item
|
||||
mus.length = int64(len(mus.items))
|
||||
mus.Unlock()
|
||||
atomic.AddInt64(&mus.length, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -325,12 +329,17 @@ func (mus *MemoryUserStore) CacheAddUnsafe(item *User) error {
|
|||
return ErrStoreCapacityOverflow
|
||||
}
|
||||
mus.items[item.ID] = item
|
||||
atomic.AddInt64(&mus.length, 1)
|
||||
mus.length = int64(len(mus.items))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mus *MemoryUserStore) CacheRemove(id int) error {
|
||||
mus.Lock()
|
||||
_, ok := mus.items[id]
|
||||
if !ok {
|
||||
mus.Unlock()
|
||||
return ErrNoRows
|
||||
}
|
||||
delete(mus.items, id)
|
||||
mus.Unlock()
|
||||
atomic.AddInt64(&mus.length, -1)
|
||||
|
@ -338,11 +347,16 @@ func (mus *MemoryUserStore) CacheRemove(id int) error {
|
|||
}
|
||||
|
||||
func (mus *MemoryUserStore) CacheRemoveUnsafe(id int) error {
|
||||
_, ok := mus.items[id]
|
||||
if !ok {
|
||||
return ErrNoRows
|
||||
}
|
||||
delete(mus.items, id)
|
||||
atomic.AddInt64(&mus.length, -1)
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Change active to a bool?
|
||||
func (mus *MemoryUserStore) Create(username string, password string, email string, group int, active int) (int, error) {
|
||||
// Is this username already taken..?
|
||||
err := mus.usernameExists.QueryRow(username).Scan(&username)
|
||||
|
@ -421,7 +435,7 @@ func NewSQLUserStore() *SQLUserStore {
|
|||
|
||||
// Add an admin version of register_stmt with more flexibility?
|
||||
// create_account_stmt, err = db.Prepare("INSERT INTO
|
||||
registerStmt, err := qgen.Builder.SimpleInsert("users", "name, email, password, salt, group, is_super_admin, session, active, message", "?,?,?,?,?,0,'',?,''")
|
||||
registerStmt, err := qgen.Builder.SimpleInsert("users", "name, email, password, salt, group, is_super_admin, session, active, message, createdAt, lastActiveAt", "?,?,?,?,?,0,'',?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -527,7 +541,11 @@ func (mus *SQLUserStore) BypassGet(id int) (*User, error) {
|
|||
}
|
||||
|
||||
func (mus *SQLUserStore) Exists(id int) bool {
|
||||
return mus.exists.QueryRow(id).Scan(&id) == nil
|
||||
err := mus.exists.QueryRow(id).Scan(&id)
|
||||
if err != nil && err != ErrNoRows {
|
||||
LogError(err)
|
||||
}
|
||||
return err != ErrNoRows
|
||||
}
|
||||
|
||||
func (mus *SQLUserStore) Create(username string, password string, email string, group int, active int) (int, error) {
|
||||
|
|
Loading…
Reference in New Issue