mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-08-03 06:32:47 +00:00
Separate out INSERT/SELECT statements in place of RETURNING in SQLite
This commit is contained in:
parent
3852f5c714
commit
8bb8642560
10 changed files with 97 additions and 29 deletions
|
@ -38,6 +38,9 @@ const eventStateKeysSchema = `
|
|||
const insertEventStateKeyNIDSQL = `
|
||||
INSERT INTO roomserver_event_state_keys (event_state_key) VALUES ($1)
|
||||
ON CONFLICT DO NOTHING;
|
||||
`
|
||||
|
||||
const insertEventStateKeyNIDResultSQL = `
|
||||
SELECT event_state_key_nid FROM roomserver_event_state_keys
|
||||
WHERE rowid = last_insert_rowid();
|
||||
`
|
||||
|
@ -62,10 +65,11 @@ const bulkSelectEventStateKeySQL = `
|
|||
`
|
||||
|
||||
type eventStateKeyStatements struct {
|
||||
insertEventStateKeyNIDStmt *sql.Stmt
|
||||
selectEventStateKeyNIDStmt *sql.Stmt
|
||||
bulkSelectEventStateKeyNIDStmt *sql.Stmt
|
||||
bulkSelectEventStateKeyStmt *sql.Stmt
|
||||
insertEventStateKeyNIDStmt *sql.Stmt
|
||||
insertEventStateKeyNIDResultStmt *sql.Stmt
|
||||
selectEventStateKeyNIDStmt *sql.Stmt
|
||||
bulkSelectEventStateKeyNIDStmt *sql.Stmt
|
||||
bulkSelectEventStateKeyStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func (s *eventStateKeyStatements) prepare(db *sql.DB) (err error) {
|
||||
|
@ -75,6 +79,7 @@ func (s *eventStateKeyStatements) prepare(db *sql.DB) (err error) {
|
|||
}
|
||||
return statementList{
|
||||
{&s.insertEventStateKeyNIDStmt, insertEventStateKeyNIDSQL},
|
||||
{&s.insertEventStateKeyNIDResultStmt, insertEventStateKeyNIDResultSQL},
|
||||
{&s.selectEventStateKeyNIDStmt, selectEventStateKeyNIDSQL},
|
||||
{&s.bulkSelectEventStateKeyNIDStmt, bulkSelectEventStateKeyNIDSQL},
|
||||
{&s.bulkSelectEventStateKeyStmt, bulkSelectEventStateKeySQL},
|
||||
|
@ -85,8 +90,12 @@ func (s *eventStateKeyStatements) insertEventStateKeyNID(
|
|||
ctx context.Context, txn *sql.Tx, eventStateKey string,
|
||||
) (types.EventStateKeyNID, error) {
|
||||
var eventStateKeyNID int64
|
||||
stmt := common.TxStmt(txn, s.insertEventStateKeyNIDStmt)
|
||||
err := stmt.QueryRowContext(ctx, eventStateKey).Scan(&eventStateKeyNID)
|
||||
var err error
|
||||
insertStmt := common.TxStmt(txn, s.insertEventStateKeyNIDStmt)
|
||||
selectStmt := common.TxStmt(txn, s.insertEventStateKeyNIDResultStmt)
|
||||
if _, err = insertStmt.ExecContext(ctx, eventStateKey); err == nil {
|
||||
err = selectStmt.QueryRowContext(ctx).Scan(&eventStateKeyNID)
|
||||
}
|
||||
return types.EventStateKeyNID(eventStateKeyNID), err
|
||||
}
|
||||
|
||||
|
@ -109,7 +118,6 @@ func (s *eventStateKeyStatements) bulkSelectEventStateKeyNID(
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close() // nolint: errcheck
|
||||
|
||||
result := make(map[string]types.EventStateKeyNID, len(eventStateKeys))
|
||||
for rows.Next() {
|
||||
var stateKey string
|
||||
|
@ -134,7 +142,6 @@ func (s *eventStateKeyStatements) bulkSelectEventStateKey(
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close() // nolint: errcheck
|
||||
|
||||
result := make(map[types.EventStateKeyNID]string, len(eventStateKeyNIDs))
|
||||
for rows.Next() {
|
||||
var stateKey string
|
||||
|
|
|
@ -54,6 +54,9 @@ const eventTypesSchema = `
|
|||
const insertEventTypeNIDSQL = `
|
||||
INSERT INTO roomserver_event_types (event_type) VALUES ($1)
|
||||
ON CONFLICT DO NOTHING;
|
||||
`
|
||||
|
||||
const insertEventTypeNIDResultSQL = `
|
||||
SELECT event_type_nid FROM roomserver_event_types
|
||||
WHERE rowid = last_insert_rowid();
|
||||
`
|
||||
|
@ -70,9 +73,10 @@ const bulkSelectEventTypeNIDSQL = `
|
|||
`
|
||||
|
||||
type eventTypeStatements struct {
|
||||
insertEventTypeNIDStmt *sql.Stmt
|
||||
selectEventTypeNIDStmt *sql.Stmt
|
||||
bulkSelectEventTypeNIDStmt *sql.Stmt
|
||||
insertEventTypeNIDStmt *sql.Stmt
|
||||
insertEventTypeNIDResultStmt *sql.Stmt
|
||||
selectEventTypeNIDStmt *sql.Stmt
|
||||
bulkSelectEventTypeNIDStmt *sql.Stmt
|
||||
}
|
||||
|
||||
func (s *eventTypeStatements) prepare(db *sql.DB) (err error) {
|
||||
|
@ -83,6 +87,7 @@ func (s *eventTypeStatements) prepare(db *sql.DB) (err error) {
|
|||
|
||||
return statementList{
|
||||
{&s.insertEventTypeNIDStmt, insertEventTypeNIDSQL},
|
||||
{&s.insertEventTypeNIDResultStmt, insertEventTypeNIDResultSQL},
|
||||
{&s.selectEventTypeNIDStmt, selectEventTypeNIDSQL},
|
||||
{&s.bulkSelectEventTypeNIDStmt, bulkSelectEventTypeNIDSQL},
|
||||
}.prepare(db)
|
||||
|
@ -92,7 +97,10 @@ func (s *eventTypeStatements) insertEventTypeNID(
|
|||
ctx context.Context, eventType string,
|
||||
) (types.EventTypeNID, error) {
|
||||
var eventTypeNID int64
|
||||
err := s.insertEventTypeNIDStmt.QueryRowContext(ctx, eventType).Scan(&eventTypeNID)
|
||||
var err error
|
||||
if _, err = s.insertEventTypeNIDStmt.ExecContext(ctx, eventType); err == nil {
|
||||
err = s.insertEventTypeNIDResultStmt.QueryRowContext(ctx).Scan(&eventTypeNID)
|
||||
}
|
||||
return types.EventTypeNID(eventTypeNID), err
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ const eventsSchema = `
|
|||
depth INTEGER NOT NULL,
|
||||
event_id TEXT NOT NULL UNIQUE,
|
||||
reference_sha256 BLOB NOT NULL,
|
||||
auth_event_nids TEXT NOT NULL
|
||||
auth_event_nids TEXT NOT NULL DEFAULT '{}'
|
||||
);
|
||||
`
|
||||
|
||||
|
@ -45,6 +45,9 @@ const insertEventSQL = `
|
|||
INSERT INTO roomserver_events (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
ON CONFLICT DO NOTHING;
|
||||
`
|
||||
|
||||
const insertEventResultSQL = `
|
||||
SELECT event_nid, state_snapshot_nid FROM roomserver_events
|
||||
WHERE rowid = last_insert_rowid();
|
||||
`
|
||||
|
@ -94,6 +97,7 @@ const selectMaxEventDepthSQL = "" +
|
|||
|
||||
type eventStatements struct {
|
||||
insertEventStmt *sql.Stmt
|
||||
insertEventResultStmt *sql.Stmt
|
||||
selectEventStmt *sql.Stmt
|
||||
bulkSelectStateEventByIDStmt *sql.Stmt
|
||||
bulkSelectStateAtEventByIDStmt *sql.Stmt
|
||||
|
@ -116,6 +120,7 @@ func (s *eventStatements) prepare(db *sql.DB) (err error) {
|
|||
|
||||
return statementList{
|
||||
{&s.insertEventStmt, insertEventSQL},
|
||||
{&s.insertEventResultStmt, insertEventResultSQL},
|
||||
{&s.selectEventStmt, selectEventSQL},
|
||||
{&s.bulkSelectStateEventByIDStmt, bulkSelectStateEventByIDSQL},
|
||||
{&s.bulkSelectStateAtEventByIDStmt, bulkSelectStateAtEventByIDSQL},
|
||||
|
@ -143,10 +148,13 @@ func (s *eventStatements) insertEvent(
|
|||
) (types.EventNID, types.StateSnapshotNID, error) {
|
||||
var eventNID int64
|
||||
var stateNID int64
|
||||
err := s.insertEventStmt.QueryRowContext(
|
||||
var err error
|
||||
if _, err = s.insertEventStmt.ExecContext(
|
||||
ctx, int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID),
|
||||
eventID, referenceSHA256, eventNIDsAsArray(authEventNIDs), depth,
|
||||
).Scan(&eventNID, &stateNID)
|
||||
); err == nil {
|
||||
err = s.insertEventResultStmt.QueryRowContext(ctx).Scan(&eventNID, &stateNID)
|
||||
}
|
||||
return types.EventNID(eventNID), types.StateSnapshotNID(stateNID), err
|
||||
}
|
||||
|
||||
|
|
18
roomserver/storage/sqlite3/list.go
Normal file
18
roomserver/storage/sqlite3/list.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package sqlite3
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
type SqliteList string
|
||||
|
||||
func sqliteIn(a pq.Int64Array) string {
|
||||
var b []string
|
||||
for _, n := range a {
|
||||
b = append(b, strconv.FormatInt(n, 10))
|
||||
}
|
||||
return strings.Join(b, ",")
|
||||
}
|
|
@ -28,7 +28,7 @@ const roomsSchema = `
|
|||
CREATE TABLE IF NOT EXISTS roomserver_rooms (
|
||||
room_nid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
room_id TEXT NOT NULL UNIQUE,
|
||||
latest_event_nids TEXT NOT NULL DEFAULT '',
|
||||
latest_event_nids TEXT NOT NULL DEFAULT '{}',
|
||||
last_event_sent_nid INTEGER NOT NULL DEFAULT 0,
|
||||
state_snapshot_nid INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
@ -38,6 +38,9 @@ const roomsSchema = `
|
|||
const insertRoomNIDSQL = `
|
||||
INSERT INTO roomserver_rooms (room_id) VALUES ($1)
|
||||
ON CONFLICT DO NOTHING;
|
||||
`
|
||||
|
||||
const insertRoomNIDResultSQL = `
|
||||
SELECT room_nid FROM roomserver_rooms
|
||||
WHERE rowid = last_insert_rowid();
|
||||
`
|
||||
|
@ -56,6 +59,7 @@ const updateLatestEventNIDsSQL = "" +
|
|||
|
||||
type roomStatements struct {
|
||||
insertRoomNIDStmt *sql.Stmt
|
||||
insertRoomNIDResultStmt *sql.Stmt
|
||||
selectRoomNIDStmt *sql.Stmt
|
||||
selectLatestEventNIDsStmt *sql.Stmt
|
||||
selectLatestEventNIDsForUpdateStmt *sql.Stmt
|
||||
|
@ -69,6 +73,7 @@ func (s *roomStatements) prepare(db *sql.DB) (err error) {
|
|||
}
|
||||
return statementList{
|
||||
{&s.insertRoomNIDStmt, insertRoomNIDSQL},
|
||||
{&s.insertRoomNIDResultStmt, insertRoomNIDResultSQL},
|
||||
{&s.selectRoomNIDStmt, selectRoomNIDSQL},
|
||||
{&s.selectLatestEventNIDsStmt, selectLatestEventNIDsSQL},
|
||||
{&s.selectLatestEventNIDsForUpdateStmt, selectLatestEventNIDsForUpdateSQL},
|
||||
|
@ -80,8 +85,12 @@ func (s *roomStatements) insertRoomNID(
|
|||
ctx context.Context, txn *sql.Tx, roomID string,
|
||||
) (types.RoomNID, error) {
|
||||
var roomNID int64
|
||||
stmt := common.TxStmt(txn, s.insertRoomNIDStmt)
|
||||
err := stmt.QueryRowContext(ctx, roomID).Scan(&roomNID)
|
||||
var err error
|
||||
insertStmt := common.TxStmt(txn, s.insertRoomNIDStmt)
|
||||
resultStmt := common.TxStmt(txn, s.insertRoomNIDResultStmt)
|
||||
if _, err = insertStmt.ExecContext(ctx, roomID); err == nil {
|
||||
err = resultStmt.QueryRowContext(ctx).Scan(&roomNID)
|
||||
}
|
||||
return types.RoomNID(roomNID), err
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,16 @@ const stateSnapshotSchema = `
|
|||
CREATE TABLE IF NOT EXISTS roomserver_state_snapshots (
|
||||
state_snapshot_nid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
room_nid INTEGER NOT NULL,
|
||||
state_block_nids TEXT NOT NULL
|
||||
state_block_nids TEXT NOT NULL DEFAULT '{}'
|
||||
);
|
||||
`
|
||||
|
||||
const insertStateSQL = `
|
||||
INSERT INTO roomserver_state_snapshots (room_nid, state_block_nids)
|
||||
VALUES ($1, $2);
|
||||
`
|
||||
|
||||
const insertStateResultSQL = `
|
||||
SELECT state_snapshot_nid FROM roomserver_state_snapshots
|
||||
WHERE rowid = last_insert_rowid();
|
||||
`
|
||||
|
@ -48,6 +51,7 @@ const bulkSelectStateBlockNIDsSQL = "" +
|
|||
|
||||
type stateSnapshotStatements struct {
|
||||
insertStateStmt *sql.Stmt
|
||||
insertStateResultStmt *sql.Stmt
|
||||
bulkSelectStateBlockNIDsStmt *sql.Stmt
|
||||
}
|
||||
|
||||
|
@ -59,6 +63,7 @@ func (s *stateSnapshotStatements) prepare(db *sql.DB) (err error) {
|
|||
|
||||
return statementList{
|
||||
{&s.insertStateStmt, insertStateSQL},
|
||||
{&s.insertStateResultStmt, insertStateResultSQL},
|
||||
{&s.bulkSelectStateBlockNIDsStmt, bulkSelectStateBlockNIDsSQL},
|
||||
}.prepare(db)
|
||||
}
|
||||
|
@ -70,7 +75,9 @@ func (s *stateSnapshotStatements) insertState(
|
|||
for i := range stateBlockNIDs {
|
||||
nids[i] = int64(stateBlockNIDs[i])
|
||||
}
|
||||
err = s.insertStateStmt.QueryRowContext(ctx, int64(roomNID), pq.Int64Array(nids)).Scan(&stateNID)
|
||||
if _, err = s.insertStateStmt.ExecContext(ctx, int64(roomNID), pq.Int64Array(nids)); err == nil {
|
||||
err = s.insertStateResultStmt.QueryRowContext(ctx).Scan(&stateNID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package sqlite3
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
|
@ -244,9 +245,11 @@ func (d *Database) AddState(
|
|||
if len(state) > 0 {
|
||||
stateBlockNID, err := d.statements.selectNextStateBlockNID(ctx)
|
||||
if err != nil {
|
||||
fmt.Println("d.statements.selectNextStateBlockNID", err)
|
||||
return 0, err
|
||||
}
|
||||
if err = d.statements.bulkInsertStateData(ctx, stateBlockNID, state); err != nil {
|
||||
fmt.Println("d.statements.bulkInsertStateData", err)
|
||||
return 0, err
|
||||
}
|
||||
stateBlockNIDs = append(stateBlockNIDs[:len(stateBlockNIDs):len(stateBlockNIDs)], stateBlockNID)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue