decred.org/dcrdex@v1.0.5/server/db/driver/pg/internal/orders.go (about) 1 // This code is available on the terms of the project LICENSE.md file, 2 // also available online at https://blueoakcouncil.org/license/1.0.0. 3 4 package internal 5 6 const ( 7 // CreateOrdersTable creates a table specified via the %s printf specifier 8 // for market and limit orders. 9 CreateOrdersTable = `CREATE TABLE IF NOT EXISTS %s ( 10 oid BYTEA PRIMARY KEY, -- UNIQUE 11 type INT2, 12 sell BOOLEAN, -- TODO: ANALYZE or INDEX? 13 account_id BYTEA, -- TODO: INDEX 14 address TEXT, -- TODO:INDEX 15 client_time TIMESTAMPTZ, 16 server_time TIMESTAMPTZ, 17 commit BYTEA UNIQUE, 18 coins BYTEA, 19 quantity INT8, 20 rate INT8, 21 force INT2, 22 status INT2, 23 filled INT8, 24 epoch_idx INT8, epoch_dur INT4, 25 preimage BYTEA UNIQUE, 26 complete_time INT8 -- when the order has successfully completed all swaps 27 );` 28 29 // InsertOrder inserts a market or limit order into the specified table. 30 InsertOrder = `INSERT INTO %s (oid, type, sell, account_id, address, 31 client_time, server_time, commit, coins, quantity, 32 rate, force, status, filled, 33 epoch_idx, epoch_dur) 34 VALUES ($1, $2, $3, $4, $5, 35 $6, $7, $8, $9, $10, 36 $11, $12, $13, $14, 37 $15, $16);` 38 39 // SelectOrder retrieves all columns with the given order ID. This may be 40 // used for any table with an "oid" column (orders_active, cancels_archived, 41 // etc.). 42 SelectOrder = `SELECT oid, type, sell, account_id, address, client_time, server_time, 43 commit, coins, quantity, rate, force, status, filled 44 FROM %s WHERE oid = $1;` 45 46 SelectOrdersByStatus = `SELECT oid, type, sell, account_id, address, client_time, server_time, 47 commit, coins, quantity, rate, force, filled 48 FROM %s WHERE status = $1;` 49 50 PreimageResultsLastN = `SELECT oid, (preimage IS NULL AND status=$3) AS preimageMiss, 51 (epoch_idx+1) * epoch_dur as epochCloseTime -- when preimages are requested 52 FROM %s -- e.g. dcr_btc.orders_archived 53 WHERE account_id = $1 54 AND status >= 0 -- exclude forgiven 55 ORDER BY epochCloseTime DESC 56 LIMIT $2` // no ; 57 // NOTE: we could join with the epochs table if we really want match_time instead of epoch close time 58 59 // SelectUserOrders retrieves all columns of all orders for the given 60 // account ID. 61 SelectUserOrders = `SELECT oid, type, sell, account_id, address, client_time, server_time, 62 commit, coins, quantity, rate, force, status, filled 63 FROM %s WHERE account_id = $1;` 64 65 // SelectUserOrderStatuses retrieves the order IDs and statuses of all orders 66 // for the given account ID. Only applies to market and limit orders. 67 SelectUserOrderStatuses = `SELECT oid, status FROM %s WHERE account_id = $1;` 68 69 // SelectUserOrderStatusesByID retrieves the order IDs and statuses of the 70 // orders with the provided order IDs for the given account ID. Only applies 71 // to market and limit orders. 72 SelectUserOrderStatusesByID = `SELECT oid, status FROM %s WHERE account_id = $1 AND oid = ANY($2);` 73 74 // SelectCanceledUserOrders gets the ID of orders that were either canceled 75 // by the user or revoked/canceled by the server, but these statuses can be 76 // set by the caller. Note that revoked orders can be market or immediate 77 // limit orders that failed to swap. 78 SelectCanceledUserOrders = `SELECT oid, match_time 79 FROM %[1]s -- a archived orders table 80 JOIN %[2]s ON %[2]s.epoch_idx = %[1]s.epoch_idx AND %[2]s.epoch_dur = %[1]s.epoch_dur -- join on epochs table PK 81 WHERE account_id = $1 AND status = ANY($2) -- {orderStatusCanceled, orderStatusRevoked} 82 ORDER BY match_time DESC 83 LIMIT $3;` // The matchTime is when the order was booked, not canceled!!! 84 85 // SelectOrderByCommit retrieves the order ID for any order with the given 86 // commitment value. This applies to the cancel order tables as well. 87 SelectOrderByCommit = `SELECT oid FROM %s WHERE commit = $1;` 88 89 // SelectOrderPreimage retrieves the preimage for the order ID; 90 SelectOrderPreimage = `SELECT preimage FROM %s WHERE oid = $1;` 91 92 // SelectOrderCoinIDs retrieves the order id, sell flag, and coins for all 93 // orders in a certain table. 94 SelectOrderCoinIDs = `SELECT oid, sell, coins 95 FROM %s;` 96 97 SetOrderPreimage = `UPDATE %s SET preimage = $1 WHERE oid = $2;` 98 SetOrderCompleteTime = `UPDATE %s SET complete_time = $1 99 WHERE oid = $2;` 100 101 RetrieveCompletedOrdersForAccount = `SELECT oid, account_id, complete_time 102 FROM %s 103 WHERE account_id = $1 AND complete_time IS NOT NULL 104 ORDER BY complete_time DESC 105 LIMIT $2;` 106 107 // UpdateOrderStatus sets the status of an order with the given order ID. 108 UpdateOrderStatus = `UPDATE %s SET status = $1 WHERE oid = $2;` 109 // UpdateOrderFilledAmt sets the filled amount of an order with the given 110 // order ID. 111 UpdateOrderFilledAmt = `UPDATE %s SET filled = $1 WHERE oid = $2;` 112 // UpdateOrderStatusAndFilledAmt sets the order status and filled amount of 113 // an order with the given order ID. 114 UpdateOrderStatusAndFilledAmt = `UPDATE %s SET status = $1, filled = $2 WHERE oid = $3;` 115 116 // OrderStatus retrieves the order type, status, and filled amount for an 117 // order with the given order ID. This only applies to market and limit 118 // orders. For cancel orders, which lack a type and filled column, use 119 // CancelOrderStatus. 120 OrderStatus = `SELECT type, status, filled FROM %s WHERE oid = $1;` 121 122 // MoveOrder moves an order row from one table to another (e.g. 123 // orders_active to orders_archived), while updating the order's status and 124 // filled amounts. 125 // For example, 126 // WITH moved AS ( -- temporary table 127 // DELETE FROM dcrdex.dcr_btc.orders_active -- origin table (%s) 128 // WHERE oid = '\xDEADBEEF' -- the order to move ($1) 129 // RETURNING 130 // oid, 131 // type, 132 // sell, 133 // account_id, 134 // address, 135 // client_time, 136 // server_time, 137 // commit, 138 // coins, 139 // quantity, 140 // rate, 141 // force, 142 // 2, -- new status (%d) 143 // 123456789, -- new filled (%d) 144 // epoch_idx, epoch_dur, preimage, complete_time 145 // ) 146 // INSERT INTO dcrdex.dcr_btc.orders_archived -- destination table (%s) 147 // SELECT * FROM moved; 148 MoveOrder = `WITH moved AS ( 149 DELETE FROM %s 150 WHERE oid = $1 151 RETURNING oid, type, sell, account_id, address, 152 client_time, server_time, commit, coins, quantity, 153 rate, force, %d, %d, 154 epoch_idx, epoch_dur, preimage, complete_time 155 ) 156 INSERT INTO %s 157 SELECT * FROM moved;` 158 // TODO: consider a MoveOrderSameFilled query 159 160 PurgeBook = `WITH moved AS ( 161 DELETE FROM %s -- active orders table for market X 162 WHERE status = $1 -- booked status code 163 RETURNING oid, type, sell, account_id, address, 164 client_time, server_time, commit, coins, quantity, 165 rate, force, %d, filled, -- revoked status code 166 epoch_idx, epoch_dur, preimage, complete_time 167 ) 168 INSERT INTO %s -- archived orders table for market X 169 SELECT * FROM moved 170 RETURNING oid, sell, account_id;` 171 172 // CreateCancelOrdersTable creates a table specified via the %s printf 173 // specifier for cancel orders. 174 CreateCancelOrdersTable = `CREATE TABLE IF NOT EXISTS %s ( 175 oid BYTEA PRIMARY KEY, -- UNIQUE INDEX 176 account_id BYTEA, -- TODO: INDEX 177 client_time TIMESTAMPTZ, 178 server_time TIMESTAMPTZ, 179 commit BYTEA UNIQUE, -- null for server-generated cancels (order revocations) 180 target_order BYTEA, -- cancel orders ref another order 181 status INT2, 182 epoch_idx INT8, epoch_dur INT4, -- 0 for rule-based revocations, -1 for exempt (e.g. book purge) 183 epoch_gap INT4 DEFAULT -1, -- epochs between order and cancel order. -1 for revocations 184 preimage BYTEA UNIQUE -- null before preimage collection, and all server-generated cancels (revocations) 185 );` 186 187 SelectCancelOrder = `SELECT oid, account_id, client_time, server_time, 188 commit, target_order, status 189 FROM %s WHERE oid = $1;` 190 191 SelectCancelOrdersByStatus = `SELECT account_id, client_time, server_time, 192 commit, target_order 193 FROM %s WHERE status = $1;` 194 195 CancelPreimageResultsLastN = `SELECT oid, (preimage IS NULL AND status=$3) AS preimageMiss, -- orderStatusRevoked 196 (epoch_idx+1) * epoch_dur AS epochCloseTime -- when preimages are requested 197 FROM %s -- e.g. dcr_btc.cancels_archived 198 WHERE account_id = $1 199 AND commit IS NOT NULL -- commit NOT NULL to exclude server-generated cancels 200 AND status >= 0 -- not forgiven 201 ORDER BY epochCloseTime DESC 202 LIMIT $2` // no ; 203 204 // SelectRevokeCancels retrieves server-initiated cancels (revokes). 205 SelectRevokeCancels = `SELECT oid, target_order, server_time, epoch_idx 206 FROM %s 207 WHERE account_id = $1 AND status = $2 -- use orderStatusRevoked 208 ORDER BY server_time DESC 209 LIMIT $3;` 210 211 // RetrieveCancelsForUserByStatus gets matched cancel orders by user and 212 // status, where status should be orderStatusExecuted. This query may be 213 // followed by a SELECT of match_time from the epochs table for the epoch 214 // IDs (idx:dur) returned by this query. In general, this query will be used 215 // on a market's archived cancels table, which includes matched cancels. 216 RetrieveCancelsForUserByStatus = `SELECT oid, target_order, epoch_idx, epoch_dur 217 FROM %s 218 WHERE account_id = $1 AND status = $2 219 ORDER BY epoch_idx * epoch_dur DESC;` 220 // RetrieveCancelTimesForUserByStatus is similar to 221 // RetrieveCancelsForUserByStatus, but it joins on an epochs table to get 222 // the match_time directly instead of the epoch_idx and epoch_dur. The 223 // cancels table, with full market schema, is %[1]s, while the epochs table 224 // is %[2]s. 225 RetrieveCancelTimesForUserByStatus = `SELECT oid, target_order, epoch_gap, match_time 226 FROM %[1]s -- a cancels table 227 JOIN %[2]s ON %[2]s.epoch_idx = %[1]s.epoch_idx AND %[2]s.epoch_dur = %[1]s.epoch_dur -- join on epochs table PK 228 WHERE account_id = $1 AND status = $2 229 ORDER BY match_time DESC 230 LIMIT $3;` // NOTE: find revoked orders via SelectRevokeCancels 231 232 // InsertCancelOrder inserts a cancel order row into the specified table. 233 InsertCancelOrder = `INSERT INTO %s (oid, account_id, client_time, server_time, 234 commit, target_order, status, epoch_idx, epoch_dur, epoch_gap) 235 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);` 236 237 // CancelOrderStatus retrieves an order's status 238 CancelOrderStatus = `SELECT status FROM %s WHERE oid = $1;` 239 240 // MoveCancelOrder, like MoveOrder, moves an order row from one table to 241 // another. However, for a cancel order, only status column is updated. 242 MoveCancelOrder = `WITH moved AS ( 243 DELETE FROM %s 244 WHERE oid = $1 245 RETURNING oid, account_id, client_time, server_time, commit, target_order, %d, epoch_idx, epoch_dur, epoch_gap, preimage 246 ) 247 INSERT INTO %s (oid, account_id, client_time, server_time, commit, target_order, status, epoch_idx, epoch_dur, epoch_gap, preimage) 248 SELECT * FROM moved;` 249 )