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 #55tags/v0.7.0
@@ -483,7 +483,7 @@ func connectToDatabase(app *app) { | |||||
log.Error("SQLite database filename value in config.ini is empty.") | log.Error("SQLite database filename value in config.ini is empty.") | ||||
os.Exit(1) | 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) | db.SetMaxOpenConns(1) | ||||
} else { | } else { | ||||
log.Error("Invalid database type '%s'. Only 'mysql' and 'sqlite3' are supported right now.", app.cfg.Database.Type) | log.Error("Invalid database type '%s'. Only 'mysql' and 'sqlite3' are supported right now.", app.cfg.Database.Type) | ||||
@@ -13,13 +13,24 @@ | |||||
package writefreely | package writefreely | ||||
import ( | import ( | ||||
"database/sql" | |||||
"github.com/go-sql-driver/mysql" | "github.com/go-sql-driver/mysql" | ||||
"github.com/mattn/go-sqlite3" | "github.com/mattn/go-sqlite3" | ||||
"github.com/writeas/web-core/log" | "github.com/writeas/web-core/log" | ||||
"regexp" | |||||
) | ) | ||||
func init() { | func init() { | ||||
SQLiteEnabled = true | 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 { | func (db *datastore) isDuplicateKeyErr(err error) bool { | ||||
@@ -1139,7 +1139,14 @@ func (db *datastore) GetPostsTagged(c *Collection, tag string, page int, include | |||||
if !includeFuture { | if !includeFuture { | ||||
timeCondition = "AND created <= " + db.now() | 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 { | if err != nil { | ||||
log.Error("Failed selecting from posts: %v", err) | log.Error("Failed selecting from posts: %v", err) | ||||
return nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't retrieve collection posts."} | return nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't retrieve collection posts."} | ||||