getRecentXIDs fetches a list of XID8 identifiers from the 'transactions' table for all transactions committed after a specified XID value. Parameters: - ctx: A context to control the execution lifetime. - value: The transaction XID after which we need the changes. - tenantID: The ID of t
(ctx context.Context, value uint64, tenantID string)
| 158 | // - A slice of XID8 identifiers. |
| 159 | // - An error if the query fails to execute, or other error occurs during its execution. |
| 160 | func (w *Watch) getRecentXIDs(ctx context.Context, value uint64, tenantID string) ([]db.XID8, error) { |
| 161 | // Convert the value to a string formatted as a Postgresql XID8 type. |
| 162 | valStr := fmt.Sprintf("'%v'::xid8", value) |
| 163 | |
| 164 | subquery := fmt.Sprintf("(select pg_xact_commit_timestamp(id::xid) from transactions where id = %s)", valStr) |
| 165 | |
| 166 | // Build the main query to get transactions committed after the one with a given XID, |
| 167 | // still visible in the current snapshot, ordered by their commit timestamps. |
| 168 | builder := w.database.Builder.Select("id"). |
| 169 | From(TransactionsTable). |
| 170 | Where(fmt.Sprintf("pg_xact_commit_timestamp(id::xid) > (%s)", subquery)). |
| 171 | Where("id < pg_snapshot_xmin(pg_current_snapshot())"). |
| 172 | Where(squirrel.Eq{"tenant_id": tenantID}). |
| 173 | OrderBy("pg_xact_commit_timestamp(id::xid)") |
| 174 | |
| 175 | // Convert the builder to a SQL query and arguments. |
| 176 | query, args, err := builder.ToSql() |
| 177 | if err != nil { |
| 178 | slog.ErrorContext(ctx, "error while building sql query", slog.Any("error", err)) |
| 179 | return nil, err |
| 180 | } |
| 181 | |
| 182 | slog.DebugContext(ctx, "executing SQL query to get recent transaction", slog.Any("query", query), slog.Any("arguments", args)) |
| 183 | // Execute transaction query |
| 184 | // Execute the SQL query. |
| 185 | rows, err := w.database.ReadPool.Query(ctx, query, args...) |
| 186 | if err != nil { |
| 187 | slog.ErrorContext(ctx, "failed to execute SQL query", slog.Any("error", err)) |
| 188 | return nil, err |
| 189 | } |
| 190 | defer rows.Close() |
| 191 | |
| 192 | // Loop through the rows and append XID8 values to the results. |
| 193 | var xids []db.XID8 |
| 194 | for rows.Next() { |
| 195 | var xid db.XID8 |
| 196 | err := rows.Scan(&xid) |
| 197 | if err != nil { |
| 198 | slog.ErrorContext(ctx, "error while scanning row", slog.Any("error", err)) |
| 199 | return nil, err |
| 200 | } |
| 201 | xids = append(xids, xid) |
| 202 | } |
| 203 | |
| 204 | // Check for errors that could have occurred during iteration. |
| 205 | err = rows.Err() |
| 206 | if err != nil { |
| 207 | slog.ErrorContext(ctx, "failed to iterate over rows", slog.Any("error", err)) |
| 208 | return nil, err |
| 209 | } |
| 210 | |
| 211 | slog.DebugContext(ctx, "successfully retrieved recent transaction", slog.Any("ids", xids)) |
| 212 | return xids, nil |
| 213 | } |
| 214 | |
| 215 | // getChanges is a method that retrieves the changes that occurred in the relation tuples within a specified transaction. |
| 216 | // |
no test coverage detected