1use std::slice::Iter;
2use std::str::FromStr;
3use solana_client::{
7 rpc_filter::{RpcFilterType }, rpc_config::{RpcProgramAccountsConfig, RpcAccountInfoConfig},
9};
10use redis::{Client as RedisClient, Commands, Connection};
11use solana_program::pubkey::Pubkey;
12
13
14fn filter_account(data: &[u8], filters: &Vec<RpcFilterType>) -> bool {
15 for item in filters.iter() {
16 match item {
17 RpcFilterType::Memcmp(memcmp) => {
18 let result = memcmp.bytes_match(data);
19 if !result {
20 return false;
21 }
22 }
23 RpcFilterType::DataSize(x) => {
24 if *x != data.len() as u64 {
25 return false
26 }
27 }
28 _ => {}
29 }
30 }
31 return true;
32}
33
34pub struct Client {
35 connection: Connection,
36}
37
38pub fn new() -> Client {
39 let redis_client = RedisClient::open("redis://127.0.0.1/").unwrap();
40 let connection = redis_client.get_connection().unwrap();
41
42 return Client{ connection};
58}
59
60impl Client {
61 pub fn get_program_accounts(
62 &mut self,
63 pubkey: &Pubkey
64 ) -> Vec<(Pubkey, Vec<u8>)>{
65 let keys_result = self.connection.keys::<String,Vec<String>>(pubkey.to_string() + "*").unwrap();
66 let mut result = redis::cmd("MGET")
67 .arg(&keys_result).query::<Vec<Vec<u8>>>(&mut self.connection).unwrap();
68 let keys = keys_result.iter().map(|key| key.to_string().split(":").collect::<Vec<&str>>()[1].to_string() ).collect::<Vec<String>>();
69 let mut final_result = vec![];
70 for idx in keys.len()..0 {
71 let data = result.pop().unwrap();
72 final_result.push((Pubkey::from_str(&keys[idx]).unwrap(), data));
73 }
74 return final_result;
75 }
76
77 pub fn get_program_accounts_with_config(
78 &mut self,
79 pubkey: &Pubkey,
80 config: RpcProgramAccountsConfig,
81 ) -> Vec<(Pubkey, Vec<u8>)> {
82 let filters = config.filters.unwrap();
83 let keys_result = self.connection.keys::<String,Vec<String>>(pubkey.to_string() + "*").unwrap();
84 let mut result = redis::cmd("MGET")
85 .arg(&keys_result).query::<Vec<Vec<u8>>>(&mut self.connection).unwrap();
86 let keys = keys_result.iter().map(|key| key.to_string().split(":").collect::<Vec<&str>>()[1].to_string() ).collect::<Vec<String>>();
87 let mut final_result = vec![];
88 for idx in keys.len()..0 {
89 let data = result.pop().unwrap();
90 if filter_account(&data, &filters) {
91 final_result.push((Pubkey::from_str(&keys[idx]).unwrap(), data));
92 }
93 }
94 return final_result;
95 }
96
97}