1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-08-20 09:26:23 -07:00

Add support for sql.Tx transactions to gcsql

This commit is contained in:
Eggbertx 2022-02-24 17:26:29 -08:00
parent 60fd5451bf
commit d0a6341bf6
6 changed files with 91 additions and 61 deletions

View file

@ -19,30 +19,7 @@ func (m *Pre2021Migrator) MigrateBoards() error {
}
// get boards from old db
rows, err := m.db.QuerySQL(`SELECT
id,
dir,
type,
upload_type,
title,
subtitle,
description,
section,
max_file_size,
max_pages,
default_style,
locked,
anonymous,
forced_anon,
max_age,
autosage_after,
no_images_after,
max_message_length,
embeds_allowed,
redirect_to_thread,
require_file,
enable_catalog
FROM DBPREFIXboards`)
rows, err := m.db.QuerySQL(boardsQuery)
if err != nil {
return err
}

View file

@ -50,34 +50,7 @@ func (m *Pre2021Migrator) MigratePosts() error {
}
func (m *Pre2021Migrator) migrateThreads() error {
rows, err := m.db.QuerySQL(`SELECT
id,
boardid,
parentid,
name,
tripcode,
email,
subject,
message,
message_raw,
password,
filename,
filename_original,
file_checksum,
filesize,
image_w,
image_h,
thumb_w,
thumb_h,
ip,
tag,
timestamp,
autosage,
deleted_timestamp,
bumped,
stickied,
locked,
reviewed from DBPREFIXposts WHERE deleted_timestamp = NULL`)
rows, err := m.db.QuerySQL(postsQuery)
if err != nil {
return err
}
@ -113,7 +86,7 @@ func (m *Pre2021Migrator) migrateThreads() error {
&post.locked,
&post.reviewed,
); err != nil {
// return err
return err
}
_, ok := m.oldBoards[post.boardid]
if !ok {

View file

@ -0,0 +1,57 @@
package pre2021
const (
boardsQuery = `SELECT
id,
dir,
type,
upload_type,
title,
subtitle,
description,
section,
max_file_size,
max_pages,
default_style,
locked,
anonymous,
forced_anon,
max_age,
autosage_after,
no_images_after,
max_message_length,
embeds_allowed,
redirect_to_thread,
require_file,
enable_catalog
FROM DBPREFIXboards`
postsQuery = `SELECT
id,
boardid,
parentid,
name,
tripcode,
email,
subject,
message,
message_raw,
password,
filename,
filename_original,
file_checksum,
filesize,
image_w,
image_h,
thumb_w,
thumb_h,
ip,
tag,
timestamp,
autosage,
deleted_timestamp,
bumped,
stickied,
locked,
reviewed from DBPREFIXposts WHERE deleted_timestamp = NULL`
)

View file

@ -1,6 +1,7 @@
package gcsql
import (
"context"
"database/sql"
"fmt"
"strings"
@ -48,7 +49,7 @@ func (db *GCDB) Close() error {
return nil
}
func (db *GCDB) PrepareSQL(query string) (*sql.Stmt, error) {
func (db *GCDB) PrepareSQL(query string, tx *sql.Tx) (*sql.Stmt, error) {
var preparedStr string
switch db.driver {
@ -66,7 +67,13 @@ func (db *GCDB) PrepareSQL(query string) (*sql.Stmt, error) {
default:
return nil, ErrUnsupportedDB
}
stmt, err := db.db.Prepare(db.replacer.Replace((preparedStr)))
var stmt *sql.Stmt
var err error
if tx != nil {
stmt, err = tx.Prepare(db.replacer.Replace(preparedStr))
} else {
stmt, err = db.db.Prepare(db.replacer.Replace(preparedStr))
}
if err != nil {
return stmt, fmt.Errorf("error preparing sql query:\n%s\n%s", query, err.Error())
}
@ -81,7 +88,7 @@ Example:
result, err := db.ExecSQL("INSERT INTO tablename (intval,stringval) VALUES(?,?)", intVal, stringVal)
*/
func (db *GCDB) ExecSQL(query string, values ...interface{}) (sql.Result, error) {
stmt, err := db.PrepareSQL(query)
stmt, err := db.PrepareSQL(query, nil)
if err != nil {
return nil, err
}
@ -89,6 +96,15 @@ func (db *GCDB) ExecSQL(query string, values ...interface{}) (sql.Result, error)
return stmt.Exec(values...)
}
/*
BeginTx creates and returns a new SQL transaction. Note that it doesn't use gochan's database variables,
e.g. DBPREFIX, DBNAME, etc so it should be used sparingly
*/
func (db *GCDB) BeginTx() (*sql.Tx, error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelSerializable})
return tx, err
}
/*
QueryRowSQL gets a row from the db with the values in values[] and fills the respective pointers in out[]
Automatically escapes the given values and caches the query
@ -101,7 +117,7 @@ Example:
[]interface{}{&intVal, &stringVal})
*/
func (db *GCDB) QueryRowSQL(query string, values, out []interface{}) error {
stmt, err := db.PrepareSQL(query)
stmt, err := db.PrepareSQL(query, nil)
if err != nil {
return err
}
@ -124,7 +140,7 @@ Example:
}
*/
func (db *GCDB) QuerySQL(query string, a ...interface{}) (*sql.Rows, error) {
stmt, err := db.PrepareSQL(query)
stmt, err := db.PrepareSQL(query, nil)
if err != nil {
return nil, err
}

View file

@ -46,7 +46,7 @@ func SetFormattedInDatabase(messages []MessagePostContainer) error {
const sql = `UPDATE DBPREFIXposts
SET message = ?
WHERE id = ?`
stmt, err := PrepareSQL(sql)
stmt, err := PrepareSQL(sql, nil)
if err != nil {
return err
}

View file

@ -16,11 +16,11 @@ var (
)
// PrepareSQL is used for generating a prepared SQL statement formatted according to the configured database driver
func PrepareSQL(query string) (*sql.Stmt, error) {
func PrepareSQL(query string, tx *sql.Tx) (*sql.Stmt, error) {
if gcdb == nil {
return nil, ErrNotConnected
}
return gcdb.PrepareSQL(query)
return gcdb.PrepareSQL(query, tx)
}
// Close closes the connection to the SQL database
@ -85,6 +85,13 @@ func QuerySQL(query string, a ...interface{}) (*sql.Rows, error) {
return gcdb.QuerySQL(query, a...)
}
func BeginTx() (*sql.Tx, error) {
if gcdb == nil {
return nil, ErrNotConnected
}
return gcdb.BeginTx()
}
// ResetBoardSectionArrays is run when the board list needs to be changed
// (board/section is added, deleted, etc)
func ResetBoardSectionArrays() {