github.com/diadata-org/diadata@v1.4.593/pkg/model/relDB.go (about) 1 package models 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/jackc/pgx/v4/pgxpool" 9 10 "github.com/diadata-org/diadata/pkg/dia" 11 "github.com/diadata-org/diadata/pkg/dia/helpers/db" 12 13 "github.com/go-redis/redis" 14 ) 15 16 // RelDatastore is a (persistent) relational database with an additional redis caching layer 17 type RelDatastore interface { 18 19 // --- Assets methods --- 20 // --------- Persistent --------- 21 SetAsset(asset dia.Asset) error 22 GetAsset(address, blockchain string) (dia.Asset, error) 23 GetAssetByID(ID string) (dia.Asset, error) 24 GetAssetsBySymbolName(symbol, name string) ([]dia.Asset, error) 25 GetAllAssets(blockchain string) ([]dia.Asset, error) 26 GetFiatAssetBySymbol(symbol string) (asset dia.Asset, err error) 27 GetAssetID(asset dia.Asset) (string, error) 28 GetPage(pageNumber uint32) ([]dia.Asset, bool, error) 29 Count() (uint32, error) 30 SetAssetVolume24H(asset dia.Asset, volume float64, timestamp time.Time) error 31 GetLastAssetVolume24H(asset dia.Asset) (float64, error) 32 GetAssetsWithVOL(starttime time.Time, numAssets int64, skip int64, onlycex bool, substring string) ([]dia.AssetVolume, error) 33 GetAssetSource(asset dia.Asset, onlycex bool) ([]string, error) 34 GetAssetsWithVolByBlockchain(starttime time.Time, endtime time.Time, blockchain string) ([]dia.AssetVolume, error) 35 36 // --------------- asset methods for exchanges --------------- 37 SetExchangePair(exchange string, pair dia.ExchangePair, cache bool) error 38 GetExchangePair(exchange string, foreignname string, caseSensitive bool) (exchangepair dia.ExchangePair, err error) 39 GetExchangePairSeparator(exchange string) (string, error) 40 GetPairsForExchange(exchange dia.Exchange, filterVerified bool, verified bool) ([]dia.ExchangePair, error) 41 GetPairsForAsset(asset dia.Asset, filterVerified bool, verified bool) ([]dia.ExchangePair, error) 42 GetExchangepairsByAsset(asset dia.Asset, exchange string, basetoken bool) ([]dia.ExchangePair, error) 43 GetExchangePairSymbols(exchange string) ([]dia.ExchangePair, error) 44 GetNumPairs(exchange dia.Exchange) (int, error) 45 SetExchangeSymbol(exchange string, symbol string) error 46 GetExchangeSymbol(exchange string, symbol string) (dia.Asset, error) 47 GetExchangeSymbols(exchange string, substring string) ([]string, error) 48 GetUnverifiedExchangeSymbols(exchange string) ([]string, error) 49 VerifyExchangeSymbol(exchange string, symbol string, assetID string) (bool, error) 50 GetExchangeSymbolAssetID(exchange string, symbol string) (string, bool, error) 51 GetAllExchangeAssets(verified bool) ([]dia.Asset, error) 52 53 // ----------------- Historical quotations methods ------------------- 54 SetHistoricalQuotation(quotation AssetQuotation) error 55 GetHistoricalQuotations(asset dia.Asset, starttime time.Time, endtime time.Time) ([]AssetQuotation, error) 56 GetLastHistoricalQuotationTimestamp(asset dia.Asset) (time.Time, error) 57 58 // ----------------- exchange methods ------------------- 59 SetExchange(exchange dia.Exchange) error 60 GetExchange(name string) (dia.Exchange, error) 61 GetAllExchanges() ([]dia.Exchange, error) 62 GetExchangeNames() ([]string, error) 63 64 // ----------------- pool methods ------------------- 65 SetPool(pool dia.Pool) error 66 SetScraperIndex(exchange string, scraperType string, indexType string, index int64) error 67 GetScraperIndex(exchange string, scraperType string) (string, int64, error) 68 GetAllDEXPoolsCount() (map[string]int, error) 69 GetPoolByAddress(blockchain string, address string) (pool dia.Pool, err error) 70 GetAllPoolAddrsExchange(exchange string, liquiThreshold float64) ([]string, error) 71 GetAllPoolsExchange(exchange string, liquiThreshold float64) ([]dia.Pool, error) 72 GetPoolsByAsset(asset dia.Asset, liquidityThreshold float64, liquidityThresholdUSD float64) ([]dia.Pool, error) 73 74 // ----------------- blockchain methods ------------------- 75 SetBlockchain(blockchain dia.BlockChain) error 76 GetBlockchain(name string) (dia.BlockChain, error) 77 GetAllAssetsBlockchains() ([]string, error) 78 GetAllBlockchains(fullAsset bool) ([]dia.BlockChain, error) 79 80 // ------ Caching ------ 81 SetAssetCache(asset dia.Asset) error 82 GetAssetCache(blockchain string, address string) (dia.Asset, error) 83 SetExchangePairCache(exchange string, pair dia.ExchangePair) error 84 GetExchangePairCache(exchange string, foreignName string) (dia.ExchangePair, error) 85 CountCache() (uint32, error) 86 87 // General methods 88 GetKeys(table string) ([]string, error) 89 90 // Scraper config and state 91 GetScraperState(ctx context.Context, scraperName string, state ScraperState) error 92 SetScraperState(ctx context.Context, scraperName string, state ScraperState) error 93 GetScraperConfig(ctx context.Context, scraperName string, config ScraperConfig) error 94 SetScraperConfig(ctx context.Context, scraperName string, config ScraperConfig) error 95 96 // Blockchain data 97 SetBlockData(dia.BlockData) error 98 GetBlockData(blockchain string, blocknumber int64) (dia.BlockData, error) 99 GetLastBlockBlockscraper(blockchain string) (int64, error) 100 101 //Oracle builder 102 SetKeyPair(publickey string, privatekey string) error 103 GetKeyPairID(publickey string) string 104 GetFeederAccessByID(id string) (owner string) 105 GetFeederByID(id string) (owner string) 106 SetOracleConfig(ctx context.Context, customerId, address, feederID, owner, feederAddress, symbols, feedSelection, chainID, frequency, sleepseconds, deviationpermille, blockchainnode, mandatoryFrequency, name string, draft, billable bool) error 107 SetFeederConfig(feederid, oracleconfigid string) error 108 GetFeederID(address string) (feederId string) 109 GetFeederLimit(owner string) (limit int) 110 GetTotalOracles(customerid string) (total int) 111 GetOracleConfig(address, chainid string) (oracleconfig dia.OracleConfig, err error) 112 ChangeOracleState(feederID string, active bool) (err error) 113 DeleteOracle(feederID string) (err error) 114 GetOraclesByOwner(owner string) (oracleconfigs []dia.OracleConfig, err error) 115 GetOraclesByCustomer(customerId string) (oracleconfigs []dia.OracleConfig, err error) 116 117 GetAllFeeders(bool, bool) (oracleconfigs []dia.OracleConfig, err error) 118 GetFeederResources() (addresses []string, err error) 119 GetOracleUpdates(address string, chainid string, offset int) ([]dia.OracleUpdate, error) 120 GetOracleUpdateCount(address string, chainid string, symbol string) (int64, error) 121 UpdateFeederAddressCheckSum(oracleaddress string) error 122 GetExpiredFeeders() (oracleconfigs []dia.OracleConfig, err error) 123 GetFeeder(feederID string) (oracleconfig dia.OracleConfig, err error) 124 125 GetDayWiseUpdates(address string, chainid string) ([]dia.FeedUpdates, float64, float64, error) 126 GetOracleLastUpdate(address, chainid, symbol string) (time.Time, string, error) 127 GetOracleUpdatesByTimeRange(address, chainid, symbol string, offset int, startTime, endTime time.Time) ([]dia.OracleUpdate, error) 128 129 // Asset List methods 130 SetAssetList(asset dia.AssetList) error 131 GetAssetListBySymbol(symbol string, listname string) ([]dia.AssetList, error) 132 DeleteAssetList(sheetName string) error 133 134 CreateCustomer(email string, name string, customerPlan int, paymentStatus string, paymentSource string, numberOfDataFeeds int, walletPublicKeys []string) error 135 AddWalletKeys(owner, username, accessLevel string, publicKey []string, customerId string) error 136 137 GetTempWalletRequest(ctx context.Context, publicKey, customerId string) (keyId int, accessLevel, username string, err error) 138 DeleteTempWalletRequest(ctx context.Context, keyId string) (err error) 139 140 AddTempWalletKeys(owner, username, accessLevel string, publicKey []string) error 141 142 UpdateAccessLevel(username, accessLevel, publicKey string) error 143 RemoveWalletKeys(publicKey []string) error 144 GetCustomerIDByWalletPublicKey(publicKey string) (int, error) 145 GetCustomerByPublicKey(publicKey string) (*Customer, error) 146 GetPendingPublicKeyByCustomer(ctx context.Context, customerId string) (pk []PublicKey, err error) 147 148 GetPendingInvites(ctx context.Context, publicKey string) (pk []PublicKey, err error) 149 150 UpdateCustomerPlan(ctx context.Context, customerID int, customerPlan int, paymentSource string, lastPayment string, payerAddress string) error 151 GetAccessLevel(publicKey string) (string, error) 152 153 GetAllChains() (chainconfigs []dia.ChainConfig, err error) 154 GetTotalGasSpend(address string, chainid string) (float64, error) 155 GetBalanceRemaining(address string, chainid string) (float64, error) 156 GetLastOracleUpdate(address string, chainid string) ([]dia.OracleUpdate, error) 157 GetLastPaymentByEndUser(endUser string) (LoopPaymentTransferProcessed, error) 158 159 GetPlan(ctx context.Context, planID int) (*Plan, error) 160 GetLastPaymentByAgreementID(agreementID string) (*LoopPaymentTransferProcessed, error) 161 InsertLoopPaymentTransferProcessed(ctx context.Context, record LoopPaymentTransferProcessed) error 162 InsertLoopPaymentResponse(ctx context.Context, response LoopPaymentResponse) error 163 GetLoopPaymentResponseByAgreementID(ctx context.Context, agreementID string) (*LoopPaymentResponse, error) 164 GetLoopPaymentResponseByCustomerID(ctx context.Context, customerID string) (*LoopPaymentResponse, error) 165 ChangeEcosystemConfig(oracleAddress string, enable bool) (err error) 166 } 167 168 const ( 169 170 // postgres tables 171 assetTable = "asset" 172 assetIdent = "assetIdent" 173 exchangepairTable = "exchangepair" 174 exchangesymbolTable = "exchangesymbol" 175 poolTable = "pool" 176 poolassetTable = "poolasset" 177 scraperCronjobStateTable = "scraper_cronjob_state" 178 exchangeTable = "exchange" 179 chainconfigTable = "chainconfig" 180 blockchainTable = "blockchain" 181 assetVolumeTable = "assetvolume" 182 historicalQuotationTable = "historicalquotation" 183 pollingTable = "polling" 184 swapRelationTable = "swap_relation" 185 // cache keys 186 keyAssetCache = "dia_asset_" 187 keyExchangePairCache = "dia_exchangepair_" 188 189 blockdataTable = "blockdata" 190 scrapersTable = "scrapers" 191 keypairTable = "keypair" 192 oracleconfigTable = "oracleconfig" 193 feederconfigTable = "feederconfig" 194 feederaccessTable = "feederaccess" 195 feederResourceTable = "feederresource" 196 feederupdatesTable = "feederupdates" 197 198 // time format for blockchain genesis dates 199 // timeFormatBlockchain = "2006-01-02" 200 ) 201 202 // RelDB is a relative database with redis caching layer. 203 type RelDB struct { 204 URI string 205 postgresClient *pgxpool.Pool 206 redisClient *redis.Client 207 redisPipe redis.Pipeliner 208 pagesize uint32 209 } 210 211 // NewRelDataStore returns a datastore with postgres client and redis cache. 212 func NewRelDataStore() (*RelDB, error) { 213 log.Info("NewRelDataStore: Initialised") 214 return NewRelDataStoreWithOptions(true, true) 215 } 216 217 // NewPostgresDataStore returns a datastore with postgres client and without redis caching layer. 218 func NewPostgresDataStore() (*RelDB, error) { 219 return NewRelDataStoreWithOptions(true, false) 220 } 221 222 // NewCachingLayer returns a datastore with redis caching layer and without postgres client. 223 func NewCachingLayer() (*RelDB, error) { 224 return NewRelDataStoreWithOptions(false, true) 225 } 226 227 // NewRelDataStoreWithOptions returns a postgres datastore and/or redis caching layer. 228 func NewRelDataStoreWithOptions(withPostgres bool, withRedis bool) (*RelDB, error) { 229 var ( 230 postgresClient *pgxpool.Pool 231 redisClient *redis.Client 232 redisPipe redis.Pipeliner 233 url string 234 ) 235 236 if withPostgres { 237 url = db.GetPostgresURL() 238 postgresClient = db.PostgresDatabase() 239 } 240 if withRedis { 241 redisClient = db.GetRedisClient() 242 redisPipe = redisClient.TxPipeline() 243 } 244 return &RelDB{url, postgresClient, redisClient, redisPipe, 32}, nil 245 } 246 247 // GetKeys returns a slice of strings holding the names of the keys of @table in postgres 248 func (rdb *RelDB) GetKeys(table string) (keys []string, err error) { 249 query := fmt.Sprintf("SELECT column_name from information_schema.columns WHERE table_name='%s'", table) 250 rows, err := rdb.postgresClient.Query(context.Background(), query) 251 if err != nil { 252 return 253 } 254 defer rows.Close() 255 256 for rows.Next() { 257 val, err := rows.Values() 258 if err != nil { 259 return keys, err 260 } 261 keys = append(keys, val[0].(string)) 262 } 263 return 264 }