diff --git a/database.go b/database.go index e61ef43..64d0fff 100644 --- a/database.go +++ b/database.go @@ -6,6 +6,7 @@ import ( "errors" "log" "os" + "strings" "sync" "github.com/gchaincl/sqlhooks/v2" @@ -63,25 +64,18 @@ func (a *goBlog) openDatabase(file string, logging bool) (*database, error) { var dr driver.Driver = &sqlite.SQLiteDriver{ ConnectHook: func(c *sqlite.SQLiteConn) error { // Register functions - // Depends on app - if err := c.RegisterFunc("mdtext", a.renderText, true); err != nil { - return err - } - // Independent - if err := c.RegisterFunc("tolocal", toLocalSafe, true); err != nil { - return err - } - if err := c.RegisterFunc("toutc", toUTCSafe, true); err != nil { - return err - } - if err := c.RegisterFunc("wordcount", wordCount, true); err != nil { - return err - } - if err := c.RegisterFunc("charcount", charCount, true); err != nil { - return err - } - if err := c.RegisterFunc("urlize", urlize, true); err != nil { - return err + for n, f := range map[string]interface{}{ + "mdtext": a.renderText, + "tolocal": toLocalSafe, + "toutc": toUTCSafe, + "wordcount": wordCount, + "charcount": charCount, + "urlize": urlize, + "lowerx": strings.ToLower, + } { + if err := c.RegisterFunc(n, f, true); err != nil { + return err + } } return nil }, diff --git a/postsDb.go b/postsDb.go index 5afd5a1..6fd4638 100644 --- a/postsDb.go +++ b/postsDb.go @@ -288,7 +288,7 @@ func buildPostsQuery(c *postsRequestConfig, selection string) (query string, arg } } if c.taxonomy != nil && len(c.taxonomyValue) > 0 { - queryBuilder.WriteString(" and path in (select path from post_parameters where parameter = @taxname and lower(value) = lower(@taxval))") + queryBuilder.WriteString(" and path in (select path from post_parameters where parameter = @taxname and lowerx(value) = lowerx(@taxval))") args = append(args, sql.Named("taxname", c.taxonomy.Name), sql.Named("taxval", c.taxonomyValue)) } if len(c.sections) > 0 { diff --git a/webmention.go b/webmention.go index 1a886fe..80fd49e 100644 --- a/webmention.go +++ b/webmention.go @@ -89,7 +89,7 @@ func (a *goBlog) extractMention(r *http.Request) (*mention, error) { func (db *database) webmentionExists(source, target string) bool { result := 0 - row, err := db.queryRow("select exists(select 1 from webmentions where lower(source) = lower(@source) and lower(target) = lower(@target))", sql.Named("source", source), sql.Named("target", target)) + row, err := db.queryRow("select exists(select 1 from webmentions where lowerx(source) = lowerx(@source) and lowerx(target) = lowerx(@target))", sql.Named("source", source), sql.Named("target", target)) if err != nil { return false } @@ -107,6 +107,23 @@ func (a *goBlog) createWebmention(source, target string) (err error) { }) } +func (db *database) insertWebmention(m *mention, status webmentionStatus) error { + _, err := db.exec( + ` + insert into webmentions (source, target, created, status, title, content, author) + values (@source, @target, @created, @status, @title, @content, @author) + `, + sql.Named("source", m.Source), + sql.Named("target", m.Target), + sql.Named("created", m.Created), + sql.Named("status", status), + sql.Named("title", m.Title), + sql.Named("content", m.Content), + sql.Named("author", m.Author), + ) + return err +} + func (db *database) deleteWebmention(id int) error { _, err := db.exec("delete from webmentions where id = @id", sql.Named("id", id)) return err @@ -146,7 +163,7 @@ func buildWebmentionsQuery(config *webmentionsRequestConfig) (query string, args if config != nil { queryBuilder.WriteString("where 1") if config.target != "" { - queryBuilder.WriteString(" and lower(target) = lower(@target)") + queryBuilder.WriteString(" and lowerx(target) = lowerx(@target)") args = append(args, sql.Named("target", config.target)) } if config.status != "" { @@ -154,8 +171,8 @@ func buildWebmentionsQuery(config *webmentionsRequestConfig) (query string, args args = append(args, sql.Named("status", config.status)) } if config.sourcelike != "" { - queryBuilder.WriteString(" and lower(source) like @sourcelike") - args = append(args, sql.Named("sourcelike", "%"+strings.ToLower(config.sourcelike)+"%")) + queryBuilder.WriteString(" and lowerx(source) like ('%' || lowerx(@sourcelike) || '%')") + args = append(args, sql.Named("sourcelike", config.sourcelike)) } if config.id != 0 { queryBuilder.WriteString(" and id = @id") diff --git a/webmentionVerification.go b/webmentionVerification.go index 495c2dd..acd35d8 100644 --- a/webmentionVerification.go +++ b/webmentionVerification.go @@ -110,11 +110,10 @@ func (a *goBlog) verifyMention(m *mention) error { } newStatus := webmentionStatusVerified if a.db.webmentionExists(m.Source, m.Target) { - _, err = a.db.exec("update webmentions set status = @status, title = @title, content = @content, author = @author where lower(source) = lower(@source) and lower(target) = lower(@target)", + _, err = a.db.exec("update webmentions set status = @status, title = @title, content = @content, author = @author where lowerx(source) = lowerx(@source) and lowerx(target) = lowerx(@target)", sql.Named("status", newStatus), sql.Named("title", m.Title), sql.Named("content", m.Content), sql.Named("author", m.Author), sql.Named("source", m.Source), sql.Named("target", m.Target)) } else { - _, err = a.db.exec("insert into webmentions (source, target, created, status, title, content, author) values (@source, @target, @created, @status, @title, @content, @author)", - sql.Named("source", m.Source), sql.Named("target", m.Target), sql.Named("created", m.Created), sql.Named("status", newStatus), sql.Named("title", m.Title), sql.Named("content", m.Content), sql.Named("author", m.Author)) + a.db.insertWebmention(m, newStatus) a.sendNotification(fmt.Sprintf("New webmention from %s to %s", m.Source, m.Target)) } return err diff --git a/webmention_test.go b/webmention_test.go new file mode 100644 index 0000000..19c12ff --- /dev/null +++ b/webmention_test.go @@ -0,0 +1,74 @@ +package main + +import ( + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_webmentions(t *testing.T) { + app := &goBlog{ + cfg: &config{ + Db: &configDb{ + File: filepath.Join(t.TempDir(), "test.db"), + }, + Server: &configServer{ + PublicAddress: "https://example.com", + }, + Blogs: map[string]*configBlog{ + "en": { + Lang: "en", + }, + }, + DefaultBlog: "en", + User: &configUser{}, + }, + } + + _ = app.initDatabase(false) + app.initComponents() + + app.db.insertWebmention(&mention{ + Source: "https://example.net/test", + Target: "https://example.com/täst", + Created: time.Now().Unix(), + Title: "Test-Title", + Content: "Test-Content", + Author: "Test-Author", + }, webmentionStatusVerified) + + mentions, err := app.db.getWebmentions(&webmentionsRequestConfig{ + sourcelike: "example.xyz", + }) + require.NoError(t, err) + assert.Len(t, mentions, 0) + + count, err := app.db.countWebmentions(&webmentionsRequestConfig{ + sourcelike: "example.net", + }) + require.NoError(t, err) + assert.Equal(t, 1, count) + + exists := app.db.webmentionExists("Https://Example.net/test", "Https://Example.com/TÄst") + assert.True(t, exists) + + mentions = app.db.getWebmentionsByAddress("https://example.com/täst") + assert.Len(t, mentions, 0) + + mentions, err = app.db.getWebmentions(&webmentionsRequestConfig{ + sourcelike: "example.net", + }) + require.NoError(t, err) + if assert.Len(t, mentions, 1) { + + app.db.approveWebmention(mentions[0].ID) + + } + + mentions = app.db.getWebmentionsByAddress("https://example.com/täst") + assert.Len(t, mentions, 1) + +}