Take in byte slices instead of strings.

This removes the need to convert from strings to byte slices and back
again as well, which I will count as a win.

Signed-off-by: Andrew (anoa) <anoa@openmailbox.org>
This commit is contained in:
Andrew (anoa) 2017-11-12 13:53:15 -08:00
parent 8c217e9f6e
commit f940f86258
No known key found for this signature in database
GPG key ID: 174BEAB009FD176D
4 changed files with 35 additions and 26 deletions

View file

@ -40,15 +40,15 @@ CREATE INDEX IF NOT EXISTS account_filter_localpart ON account_filter(localpart)
const selectFilterSQL = "" + const selectFilterSQL = "" +
"SELECT filter FROM account_filter WHERE localpart = $1 AND id = $2" "SELECT filter FROM account_filter WHERE localpart = $1 AND id = $2"
const selectFilterByContentSQL = "" + const selectFilterIDByContentSQL = "" +
"SELECT filter FROM account_filter WHERE localpart = $1 AND filter = $2" "SELECT id FROM account_filter WHERE localpart = $1 AND filter = $2"
const insertFilterSQL = "" + const insertFilterSQL = "" +
"INSERT INTO account_filter (filter, id, localpart) VALUES ($1, DEFAULT, $2) RETURNING id" "INSERT INTO account_filter (filter, id, localpart) VALUES ($1, DEFAULT, $2) RETURNING id"
type filterStatements struct { type filterStatements struct {
selectFilterStmt *sql.Stmt selectFilterStmt *sql.Stmt
selectFilterByContentStmt *sql.Stmt selectFilterIDByContentStmt *sql.Stmt
insertFilterStmt *sql.Stmt insertFilterStmt *sql.Stmt
} }
@ -60,7 +60,7 @@ func (s *filterStatements) prepare(db *sql.DB) (err error) {
if s.selectFilterStmt, err = db.Prepare(selectFilterSQL); err != nil { if s.selectFilterStmt, err = db.Prepare(selectFilterSQL); err != nil {
return return
} }
if s.selectFilterByContentStmt, err = db.Prepare(selectFilterByContentSQL); err != nil { if s.selectFilterIDByContentStmt, err = db.Prepare(selectFilterIDByContentSQL); err != nil {
return return
} }
if s.insertFilterStmt, err = db.Prepare(insertFilterSQL); err != nil { if s.insertFilterStmt, err = db.Prepare(insertFilterSQL); err != nil {
@ -71,31 +71,37 @@ func (s *filterStatements) prepare(db *sql.DB) (err error) {
func (s *filterStatements) selectFilter( func (s *filterStatements) selectFilter(
ctx context.Context, localpart string, filterID string, ctx context.Context, localpart string, filterID string,
) (filter string, err error) { ) (filter []byte, err error) {
err = s.selectFilterStmt.QueryRowContext(ctx, localpart, filterID).Scan(&filterJSON) err = s.selectFilterStmt.QueryRowContext(ctx, localpart, filterID).Scan(&filter)
return return
} }
func (s *filterStatements) insertFilter( func (s *filterStatements) insertFilter(
ctx context.Context, filter string, localpart string, ctx context.Context, filter []byte, localpart string,
) (pos string, err error) { ) (filterID string, err error) {
var existingFilter string var existingFilterID string
// This can result in a race condition when two clients try to insert the // This can result in a race condition when two clients try to insert the
// same filter and localpart at the same time, however this is not a // same filter and localpart at the same time, however this is not a
// problem as both calls will result in the same filterID // problem as both calls will result in the same filterID
filterJSON, errN := gomatrixserverlib.CanonicalJSON(filter) filterJSON, err := gomatrixserverlib.CanonicalJSON(filter)
if err { if err != nil {
return "", err return "", err
} }
// Check if filter already exists in the database // Check if filter already exists in the database
err = s.selectFilterByContentStmt.QueryRowContext(ctx, err = s.selectFilterIDByContentStmt.QueryRowContext(ctx,
localpart, filterJSON).Scan(&existingFilter) localpart, filterJSON).Scan(&existingFilterID)
if existingFilter != "" { if err != nil {
return existingFilter, err return "", err
}
// If it does, return the existing ID
if len(existingFilterID) != 0 {
return existingFilterID, err
} }
err = s.insertFilterStmt.QueryRowContext(ctx, filterJSON, localpart).Scan(&pos) // Otherwise insert the filter and return the new ID
err = s.insertFilterStmt.QueryRowContext(ctx, filterJSON, localpart).
Scan(&filterID)
return return
} }

View file

@ -321,22 +321,25 @@ func (d *Database) GetThreePIDsForLocalpart(
} }
// GetFilter looks up the filter associated with a given local user and filter ID. // GetFilter looks up the filter associated with a given local user and filter ID.
// Returns an error if no such filter exists or if there was an error taling to the database. // Returns a filter represented as a byte slice. Otherwise returns an error if
// no such filter exists or if there was an error talking to the database.
func (d *Database) GetFilter( func (d *Database) GetFilter(
ctx context.Context, localpart string, filterID string, ctx context.Context, localpart string, filterID string,
) (string, error) { ) ([]byte, error) {
return d.filter.selectFilter(ctx, localpart, filterID) return d.filter.selectFilter(ctx, localpart, filterID)
} }
// PutFilter puts the passed filter into the database. // PutFilter puts the passed filter into the database.
// Returns an error if something goes wrong. // Returns the filterID as a string. Otherwise returns an error if something
// goes wrong.
func (d *Database) PutFilter( func (d *Database) PutFilter(
ctx context.Context, localpart, filter string, ctx context.Context, localpart string, filter []byte,
) (string, error) { ) (string, error) {
return d.filter.insertFilter(ctx, filter, localpart) return d.filter.insertFilter(ctx, filter, localpart)
} }
// CheckAccountAvailability checks if the username/localpart is already present in the database. // CheckAccountAvailability checks if the username/localpart is already present
// in the database.
// If the DB returns sql.ErrNoRows the Localpart isn't taken. // If the DB returns sql.ErrNoRows the Localpart isn't taken.
func (d *Database) CheckAccountAvailability(ctx context.Context, localpart string) (bool, error) { func (d *Database) CheckAccountAvailability(ctx context.Context, localpart string) (bool, error) {
_, err := d.accounts.selectAccountByLocalpart(ctx, localpart) _, err := d.accounts.selectAccountByLocalpart(ctx, localpart)

View file

@ -60,7 +60,7 @@ func GetFilter(
} }
} }
filter := gomatrix.Filter{} filter := gomatrix.Filter{}
err = json.Unmarshal([]byte(res), &filter) err = json.Unmarshal(res, &filter)
if err != nil { if err != nil {
httputil.LogThenError(req, err) httputil.LogThenError(req, err)
} }
@ -111,7 +111,7 @@ func PutFilter(
} }
} }
filterID, err := accountDB.PutFilter(req.Context(), localpart, string(filterArray)) filterID, err := accountDB.PutFilter(req.Context(), localpart, filterArray)
if err != nil { if err != nil {
return httputil.LogThenError(req, err) return httputil.LogThenError(req, err)
} }

View file

@ -28,7 +28,6 @@ import (
"github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/common/config"
log "github.com/sirupsen/logrus"
"github.com/matrix-org/dendrite/clientapi/auth" "github.com/matrix-org/dendrite/clientapi/auth"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
@ -37,6 +36,7 @@ import (
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
log "github.com/sirupsen/logrus"
) )
const ( const (