Commit ab7162eb authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Improve query compatibility. Merge #130

parent 5196a107
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ WHERE EXISTS (SELECT id FROM users WHERE id = $2::BYTEA)

	// An invite was successfully added if both components were inserted.
	if rowsAffected, _ := res.RowsAffected(); rowsAffected != 2 {
		err = errors.New("user ID not found or unavailable")
		err = sql.ErrNoRows
		return err
	}

+1 −1
Original line number Diff line number Diff line
@@ -568,7 +568,7 @@ func leaderboardSubmit(logger *zap.Logger, db *sql.DB, caller string, leaderboar

	query = `INSERT INTO leaderboard_record (id, leaderboard_id, owner_id, handle, lang, location, timezone,
				rank_value, score, num_score, metadata, ranked_at, updated_at, updated_at_inverse, expires_at, banned_at)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, COALESCE($11, '{}'), $12, $13, $14, $15, $16)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, COALESCE($11, '{}'::BYTEA), $12, $13, $14, $15, $16)
			ON CONFLICT (leaderboard_id, expires_at, owner_id)
			DO UPDATE SET handle = $4, lang = $5, location = COALESCE($6, leaderboard_record.location),
			  timezone = COALESCE($7, leaderboard_record.timezone), ` + scoreOpSql + `, num_score = leaderboard_record.num_score + 1,
+6 −24
Original line number Diff line number Diff line
@@ -96,26 +96,8 @@ func StorageList(logger *zap.Logger, db *sql.DB, caller string, userID string, b
		}
	}

	// Select the correct index. NOTE: should be removed when DB index selection is smarter.
	index := ""
	if userID == "" {
		if collection == "" {
			index = "deleted_at_bucket_read_collection_record_user_id_idx"
		} else {
			index = "deleted_at_bucket_collection_read_record_user_id_idx"
		}
	} else {
		if bucket == "" {
			index = "deleted_at_user_id_read_bucket_collection_record_idx"
		} else if collection == "" {
			index = "deleted_at_user_id_bucket_read_collection_record_idx"
		} else {
			index = "deleted_at_user_id_bucket_collection_read_record_idx"
		}
	}

	// Set up the query.
	query := "SELECT user_id, bucket, collection, record, value, version, read, write, created_at, updated_at, expires_at FROM storage@" + index
	query := "SELECT user_id, bucket, collection, record, value, version, read, write, created_at, updated_at, expires_at FROM storage"
	params := make([]interface{}, 0)

	// If cursor is present, give keyset clause priority over other parameters.
@@ -401,19 +383,19 @@ SELECT $1, $2, $3, $4, $5, $6::BYTEA, $7, $8, $9, $10, $10, 0`
			// Simple write.
			// If needed use an additional clause to enforce permissions.
			if caller != "" {
				query += " WHERE NOT EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3 AND collection = $4 AND record = $5 AND deleted_at = 0 AND write = 0)"
				query += " WHERE NOT EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3::VARCHAR AND collection = $4::VARCHAR AND record = $5::VARCHAR AND deleted_at = 0 AND write = 0)"
			}
			query += `
ON CONFLICT (bucket, collection, user_id, record, deleted_at)
DO UPDATE SET value = $6::BYTEA, version = $7, read = $8, write = $9, updated_at = $10`
		} else if d.Version == "*" {
			// if-none-match
			query += " WHERE NOT EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3 AND collection = $4 AND record = $5 AND deleted_at = 0)"
			query += " WHERE NOT EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3::VARCHAR AND collection = $4::VARCHAR AND record = $5::VARCHAR AND deleted_at = 0)"
			// No additional clause needed to enforce permissions.
			// Any existing record, no matter its write permission, will cause this operation to be rejected.
		} else {
			// if-match
			query += " WHERE EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3 AND collection = $4 AND record = $5 AND deleted_at = 0 AND version = $11"
			query += " WHERE EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3::VARCHAR AND collection = $4::VARCHAR AND record = $5::VARCHAR AND deleted_at = 0 AND version = $11"
			// If needed use an additional clause to enforce permissions.
			if caller != "" {
				query += " AND write = 1"
@@ -566,10 +548,10 @@ SELECT $1, $2, $3, $4, $5, $6::BYTEA, $7, $8, $9, $10, $10, 0`
		params := []interface{}{generateNewId(), update.Key.UserId, update.Key.Bucket, update.Key.Collection, update.Key.Record, newValue, newVersion, update.PermissionRead, update.PermissionWrite, ts}
		if version == "" {
			// Treat this as an if-none-match.
			query += " WHERE NOT EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3 AND collection = $4 AND record = $5 AND deleted_at = 0)"
			query += " WHERE NOT EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3::VARCHAR AND collection = $4::VARCHAR AND record = $5::VARCHAR AND deleted_at = 0)"
		} else {
			// if-match
			query += " WHERE EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3 AND collection = $4 AND record = $5 AND deleted_at = 0 AND version = $11"
			query += " WHERE EXISTS (SELECT record FROM storage WHERE user_id = $2 AND bucket = $3::VARCHAR AND collection = $4::VARCHAR AND record = $5::VARCHAR AND deleted_at = 0 AND version = $11"
			// If needed use an additional clause to enforce permissions.
			if caller != "" {
				query += " AND write = 1"
+3 −1
Original line number Diff line number Diff line
@@ -312,7 +312,9 @@ func (p *pipeline) friendAddById(l *zap.Logger, session session, envelope *Envel
	}

	if err := friendAdd(logger, p.db, p.notificationService, session.UserID(), session.Handle(), friendID); err != nil {
		if err != sql.ErrNoRows {
			logger.Error("Could not add friend", zap.Error(err))
		}
		session.Send(ErrorMessageRuntimeException(envelope.CollationId, "Failed to add friend"), true)
		return
	}
+3 −3
Original line number Diff line number Diff line
@@ -856,16 +856,16 @@ func (p *pipeline) groupUserAdd(l *zap.Logger, session session, envelope *Envelo
INSERT INTO group_edge (source_id, position, updated_at, destination_id, state)
SELECT data.id, data.position, data.updated_at, data.destination, data.state
FROM (
  SELECT $1::BYTEA AS id, $2::INT AS position, $2::INT AS updated_at, $3::BYTEA AS destination, 1 AS state
  SELECT $1::BYTEA AS id, $2::BIGINT AS position, $2::BIGINT AS updated_at, $3::BYTEA AS destination, 1 AS state
  UNION ALL
  SELECT $3::BYTEA AS id, $2::INT AS position, $2::INT AS updated_at, $1::BYTEA AS destination, 1 AS state
  SELECT $3::BYTEA AS id, $2::BIGINT AS position, $2::BIGINT AS updated_at, $1::BYTEA AS destination, 1 AS state
) AS data
WHERE
  EXISTS (SELECT source_id FROM group_edge WHERE source_id = $1::BYTEA AND destination_id = $4 AND state = 0)
AND
  EXISTS (SELECT id FROM groups WHERE id = $1::BYTEA AND disabled_at = 0)
ON CONFLICT (source_id, destination_id)
DO UPDATE SET state = 1, updated_at = $2::INT`,
DO UPDATE SET state = 1, updated_at = $2::BIGINT`,
		groupID, ts, userID, session.UserID())

	if err != nil {
Loading