func (db *DB) PlaceOrder(order *match.LimitOrder) (orderid string, err error) {

	// Check that they have the balance for the order
	// if they do, place the order and update their balance
	if err = order.SetID(); err != nil {
		return
	}

	var tx *sql.Tx
	if tx, err = db.DBHandler.Begin(); err != nil {
		err = fmt.Errorf("Error beginning transaction while placing order: \n%s", err)
		return
	}

	defer func() {
		if err != nil {
			tx.Rollback()
			err = fmt.Errorf("Error while placing order: \n%s", err)
			return
		}
		err = tx.Commit()
	}()

	// use balance schema
	if _, err = tx.Exec("USE " + db.balanceSchema + ";"); err != nil {
		return
	}

	inPairs := false
	for _, pair := range db.pairsArray {
		inPairs = inPairs || pair.String() == order.TradingPair.String()
	}
	if !inPairs {
		err = fmt.Errorf("Trading pair does not exist, try the other way around (e.g. ltc/btc => btc/ltc)")
		return
	}

	var balCheckAsset string
	if order.IsBuySide() {
		balCheckAsset = order.TradingPair.AssetHave.String()
	} else {
		balCheckAsset = order.TradingPair.AssetWant.String()
	}

	getBalanceQuery := fmt.Sprintf("SELECT balance FROM %s WHERE pubkey='%x';", balCheckAsset, order.Pubkey[:])
	rows, getBalErr := tx.Query(getBalanceQuery)
	if err = getBalErr; err != nil {
		return
	}

	if rows.Next() {
		var balance uint64
		if err = rows.Scan(&balance); err != nil {
			return
		}

		if err = rows.Close(); err != nil {
			return
		}

		if balance > order.AmountHave {

			newBal := balance - order.AmountHave
			subtractBalanceQuery := fmt.Sprintf("UPDATE %s SET balance=%d WHERE pubkey='%x';", balCheckAsset, newBal, order.Pubkey[:])
			if _, err = tx.Query(subtractBalanceQuery); err != nil {
				return
			}

			if _, err = tx.Exec("USE " + db.orderSchema + ";"); err != nil {
				return
			}

			realPrice, priceErr := order.Price()
			if err = priceErr; err != nil {
				return
			}

			placeOrderQuery := fmt.Sprintf("INSERT INTO %s VALUES ('%x', '%s', '%s', %f, %d, %d, NOW());", order.TradingPair.String(), order.Pubkey[:], order.OrderID, order.Side, realPrice, order.AmountHave, order.AmountWant)
			if _, err = tx.Exec(placeOrderQuery); err != nil {
				return
			}

		} else {
			err = fmt.Errorf("Tried to place an order for more than you own, please lower the amount you want or adjust price")
			return
		}
	} else {
		err = fmt.Errorf("Could not find balance for user with pubkey %x, so cannot place order", order.Pubkey[:])
		return
	}

	orderid = order.OrderID

	if err = db.RunMatchingBestPricesWithinTransaction(&order.TradingPair, tx); err != nil {
		return
	}

	return
}
// PlaceOrder runs the queries which places an input order. Placing an individual order is atomic.
PlaceOrder runs the queries which places an input order. Placing an individual order is atomic.
// PlaceOrder runs the queries which places an input order . Placing an individual order is atomic .
func (db *DB) PlaceOrder(order *match.LimitOrder) (orderid string, err error) {
	if err = order.SetID(); err != nil {
		return
	}
	var tx *sql.Tx
	if tx, err = db.DBHandler.Begin(); err != nil {
		err = fmt.Errorf("Error beginning transaction while placing order: \n%s", err)
		return
	}
	defer func() {
		if err != nil {
			tx.Rollback()
			err = fmt.Errorf("Error while placing order: \n%s", err)
			return
		}
		err = tx.Commit()
	}()
	if _, err = tx.Exec("USE " + db.balanceSchema + ";"); err != nil {
		return
	}
	inPairs := false
	for _, pair := range db.pairsArray {
		inPairs = inPairs || pair.String() == order.TradingPair.String()
	}
	if !inPairs {
		err = fmt.Errorf("Trading pair does not exist, try the other way around (e.g. ltc/btc => btc/ltc)")
		return
	}
	var balCheckAsset string
	if order.IsBuySide() {
		balCheckAsset = order.TradingPair.AssetHave.String()
	} else {
		balCheckAsset = order.TradingPair.AssetWant.String()
	}
	getBalanceQuery := fmt.Sprintf("SELECT balance FROM %s WHERE pubkey='%x';", balCheckAsset, order.Pubkey[:])
	rows, getBalErr := tx.Query(getBalanceQuery)
	if err = getBalErr; err != nil {
		return
	}
	if rows.Next() {
		var balance uint64
		if err = rows.Scan(&balance); err != nil {
			return
		}
		if err = rows.Close(); err != nil {
			return
		}
		if balance > order.AmountHave {
			newBal := balance - order.AmountHave
			subtractBalanceQuery := fmt.Sprintf("UPDATE %s SET balance=%d WHERE pubkey='%x';", balCheckAsset, newBal, order.Pubkey[:])
			if _, err = tx.Query(subtractBalanceQuery); err != nil {
				return
			}
			if _, err = tx.Exec("USE " + db.orderSchema + ";"); err != nil {
				return
			}
			realPrice, priceErr := order.Price()
			if err = priceErr; err != nil {
				return
			}
			placeOrderQuery := fmt.Sprintf("INSERT INTO %s VALUES ('%x', '%s', '%s', %f, %d, %d, NOW());", order.TradingPair.String(), order.Pubkey[:], order.OrderID, order.Side, realPrice, order.AmountHave, order.AmountWant)
			if _, err = tx.Exec(placeOrderQuery); err != nil {
				return
			}
		} else {
			err = fmt.Errorf("Tried to place an order for more than you own, please lower the amount you want or adjust price")
			return
		}
	} else {
		err = fmt.Errorf("Could not find balance for user with pubkey %x, so cannot place order", order.Pubkey[:])
		return
	}
	orderid = order.OrderID
	if err = db.RunMatchingBestPricesWithinTransaction(&order.TradingPair, tx); err != nil {
		return
	}
	return
}
func ( db * DB ) PlaceOrder ( order * match . LimitOrder ) ( orderid string , err error ) { if err = order . SetID ( ) ; err != nil { return } var tx * sql . Tx if tx , err = db . DBHandler . Begin ( ) ; err != nil { err = fmt . Errorf ( " \n " , err ) return } defer func ( ) { if err != nil { tx . Rollback ( ) err = fmt . Errorf ( " \n " , err ) return } err = tx . Commit ( ) } ( ) if _ , err = tx . Exec ( " " + db . balanceSchema + " " ) ; err != nil { return } inPairs := false for _ , pair := range db . pairsArray { inPairs = inPairs || pair . String ( ) == order . TradingPair . String ( ) } if ! inPairs { err = fmt . Errorf ( " " ) return } var balCheckAsset string if order . IsBuySide ( ) { balCheckAsset = order . TradingPair . AssetHave . String ( ) } else { balCheckAsset = order . TradingPair . AssetWant . String ( ) } getBalanceQuery := fmt . Sprintf ( " " , balCheckAsset , order . Pubkey [ : ] ) rows , getBalErr := tx . Query ( getBalanceQuery ) if err = getBalErr ; err != nil { return } if rows . Next ( ) { var balance uint64 if err = rows . Scan ( & balance ) ; err != nil { return } if err = rows . Close ( ) ; err != nil { return } if balance > order . AmountHave { newBal := balance - order . AmountHave subtractBalanceQuery := fmt . Sprintf ( " " , balCheckAsset , newBal , order . Pubkey [ : ] ) if _ , err = tx . Query ( subtractBalanceQuery ) ; err != nil { return } if _ , err = tx . Exec ( " " + db . orderSchema + " " ) ; err != nil { return } realPrice , priceErr := order . Price ( ) if err = priceErr ; err != nil { return } placeOrderQuery := fmt . Sprintf ( " " , order . TradingPair . String ( ) , order . Pubkey [ : ] , order . OrderID , order . Side , realPrice , order . AmountHave , order . AmountWant ) if _ , err = tx . Exec ( placeOrderQuery ) ; err != nil { return } } else { err = fmt . Errorf ( " " ) return } } else { err = fmt . Errorf ( " " , order . Pubkey [ : ] ) return } orderid = order . OrderID if err = db . RunMatchingBestPricesWithinTransaction ( & order . TradingPair , tx ) ; err != nil { return } return }
PlaceOrder runs the queries which places an input order.
PlaceOrder runs the queries which places an input order .
// Check that they have the balance for the order // if they do, place the order and update their balance // use balance schema