blob: 8aa492c2a152919b78e2d18f4d19efc7a93d23fc [file] [log] [blame]
/*
Copyright 2016 The Transicator Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package common
//go:generate stringer -type Operation .
//go:generate protoc --go_out=. transicator.proto
/*
Operation lists the types of operations on each row in a change list.
*/
type Operation int
// Operation constants. (Not using "iota" here because these IDs are persisted.)
const (
Insert Operation = 1
Update Operation = 2
Delete Operation = 3
)
/*
A ColumnVal is a single column value in a result. It just contains a
value and a type.
*/
type ColumnVal struct {
// Column value, in the string format that comes straight from Postgres
Value interface{} `json:"value"`
// The Postgres type of the column, as defined in the Postgres source
Type int32 `json:"type"`
}
/*
A Row is a single row in a table. It may be aggregated into an entire set of rows
for a snapshot of a table, or into a list of row operations in a change
list. The key for each property in the row is the name of the field, and the
value is a ColumnVal that includes both the value and type.
*/
type Row map[string]*ColumnVal
/*
A TableInfo is returned when we are reading a snapshot stream. It indicates that
subsequent Rows returned will affect the specified table.
*/
type TableInfo struct {
Name string
Columns []ColumnInfo
}
/*
ColumnInfo contains information about a column -- its name and Postgres
data type.
*/
type ColumnInfo struct {
Name string
Type int32
}
/*
A Change is a list of changed rows. Each Change describes how the row changed
(due to an insert, delete, or update), when it changed (LSNs and transaction
IDs from Postgres), and what changed (the new and/or old rows).
*/
type Change struct {
// Why the row was changed: insert, update, or delete
Operation Operation `json:"operation"`
// The name of the table that was updated
Table string `json:"table"`
// A value that indicates when the row is changed. It includes the
// "commit LSN" and "CommitIndex" from below. This is the value that
// clients should return to the API when looking for a list of changes.
Sequence string `json:"sequence,omitempty"`
// The LSN when the change was committed.
CommitSequence uint64 `json:"commitSequence"`
// The Postgres LSN when the row changed. This will be interleaved
// in the change list because transactions commit at different times.
ChangeSequence uint64 `json:"changeSequence"`
// The order in which the change happened within the commit. For a transaction
// affects multiple rows, changes will be listed in order, and this value
// will begin at zero and be incremented by one.
CommitIndex uint32 `json:"commitIndex"`
// The Postgres Transaction ID when this change committed. This may be used
// to find a CommitSequence from a particular snapshot. (TXIDs are 32
// bits inside Postgres. We put the Postgres "epoch" in the high 32 bits
// so that we deliver a 64-bit value that will not wrap around.)
TransactionID uint64 `json:"txid"`
// The time when the record was inserted to the database, in seconds since
// the Unix epoch.
Timestamp int64 `json:"timestamp,omitempty"`
// For an insert operation, the columns that are being inserted. For an update,
// the new value of the columns
NewRow Row `json:"newRow,omitempty"`
// For an update oepration, the old value of the columns. For a delete, the
// value of the columns that are being deleted
OldRow Row `json:"oldRow,omitempty"`
// Sometimes we need to return an error instead of a change. If this is
// not null, then it means a replication error occurred.
Error error `json:"-"`
}
/*
GetSequence returns an object that combines the commit LSN and index.
*/
func (c *Change) GetSequence() Sequence {
return MakeSequence(uint64(c.CommitSequence), uint32(c.CommitIndex))
}
/*
A Table represents a snapshot of a table at a particular point in time.
*/
type Table struct {
Name string `json:"name"`
Rows []Row `json:"rows"`
}
/*
A Snapshot represents a consistent view of a group of tables, all generated
at a consistent point.
*/
type Snapshot struct {
// SnapshotInfo represents a Postgres transaction snapshot, in the format
// "xmin:xmax:xip1,xip2,xip3..."
SnapshotInfo string `json:"snapshotInfo"`
// Timestamp is a Postgres timestamp that describes when the snapshot was created
Timestamp string `json:"timestamp"`
// The tables in the snapshot
Tables []Table `json:"tables"`
}
/*
A ChangeList represents a set of changes returned from the change server.
It contains a list of rows, and it also contains information about the list.
*/
type ChangeList struct {
// The highest value for "Sequence" in the whole database. The
// client may use this to understand when they are at the end of the list
// of changes.
LastSequence string `json:"lastSequence"`
// The lowest value for "Sequence" in the whole database. The client
// may use this to determine if they are at the beginning of the whole
// change list and must request a new snapshot to get consistent data.
FirstSequence string `json:"firstSequence"`
// All the changes, in order of "commit sequence" and "commit index"
Changes []Change `json:"changes"`
}