From 8a555567a62c0f0aeffc6f7fbff35b629f70ecbd Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 7 Jan 2019 11:55:23 -0500 Subject: [PATCH] Fix tagged posts SQLite query SQLite doesn't have an `RLIKE` function, so the query for hashtagged posts was failing before. This adds a `regexp` function to SQLite and correctly retrieves all posts on a blog with the requested hashtag. This closes #55 --- app.go | 2 +- database-sqlite.go | 11 +++++++++++ database.go | 9 ++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app.go b/app.go index dbb8c6f..2b319a1 100644 --- a/app.go +++ b/app.go @@ -483,7 +483,7 @@ func connectToDatabase(app *app) { log.Error("SQLite database filename value in config.ini is empty.") os.Exit(1) } - db, err = sql.Open("sqlite3", app.cfg.Database.FileName+"?parseTime=true&cached=shared") + db, err = sql.Open("sqlite3_with_regex", app.cfg.Database.FileName+"?parseTime=true&cached=shared") db.SetMaxOpenConns(1) } else { log.Error("Invalid database type '%s'. Only 'mysql' and 'sqlite3' are supported right now.", app.cfg.Database.Type) diff --git a/database-sqlite.go b/database-sqlite.go index e1ed991..5fa3f6c 100644 --- a/database-sqlite.go +++ b/database-sqlite.go @@ -13,13 +13,24 @@ package writefreely import ( + "database/sql" "github.com/go-sql-driver/mysql" "github.com/mattn/go-sqlite3" "github.com/writeas/web-core/log" + "regexp" ) func init() { SQLiteEnabled = true + + regex := func(re, s string) (bool, error) { + return regexp.MatchString(re, s) + } + sql.Register("sqlite3_with_regex", &sqlite3.SQLiteDriver{ + ConnectHook: func(conn *sqlite3.SQLiteConn) error { + return conn.RegisterFunc("regexp", regex, true) + }, + }) } func (db *datastore) isDuplicateKeyErr(err error) bool { diff --git a/database.go b/database.go index 28a7e3b..47e61eb 100644 --- a/database.go +++ b/database.go @@ -1139,7 +1139,14 @@ func (db *datastore) GetPostsTagged(c *Collection, tag string, page int, include if !includeFuture { timeCondition = "AND created <= " + db.now() } - rows, err := db.Query("SELECT "+postCols+" FROM posts WHERE collection_id = ? AND LOWER(content) RLIKE ? "+timeCondition+" ORDER BY created "+order+limitStr, collID, "#"+strings.ToLower(tag)+"[[:>:]]") + + var rows *sql.Rows + var err error + if db.driverName == driverSQLite { + rows, err = db.Query("SELECT "+postCols+" FROM posts WHERE collection_id = ? AND LOWER(content) regexp ? "+timeCondition+" ORDER BY created "+order+limitStr, collID, `.*#`+strings.ToLower(tag)+`\b.*`) + } else { + rows, err = db.Query("SELECT "+postCols+" FROM posts WHERE collection_id = ? AND LOWER(content) RLIKE ? "+timeCondition+" ORDER BY created "+order+limitStr, collID, "#"+strings.ToLower(tag)+"[[:>:]]") + } if err != nil { log.Error("Failed selecting from posts: %v", err) return nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't retrieve collection posts."}