diff --git a/chaindexing/src/contract_states.rs b/chaindexing/src/contract_states.rs index f9bd9ef..871191d 100644 --- a/chaindexing/src/contract_states.rs +++ b/chaindexing/src/contract_states.rs @@ -163,7 +163,11 @@ pub fn serde_map_to_string_map( ) -> HashMap { serde_map.iter().fold(HashMap::new(), |mut map, (key, value)| { if !value.is_null() { - map.insert(key.to_owned(), value.to_string().replace("\"", "")); + if value.is_object() { + map.insert(key.to_owned(), value.to_string()); + } else { + map.insert(key.to_owned(), value.to_string().replace("\"", "")); + } } map diff --git a/chaindexing/src/contract_states/migrations.rs b/chaindexing/src/contract_states/migrations.rs index 79d336f..25150a7 100644 --- a/chaindexing/src/contract_states/migrations.rs +++ b/chaindexing/src/contract_states/migrations.rs @@ -47,7 +47,7 @@ pub trait ContractStateMigrations: Send + Sync { let state_versions_table_name = extract_table_name(&create_state_versions_table_migration); let state_versions_fields = - extract_table_fields(&create_state_versions_table_migration); + extract_table_fields(&create_state_versions_table_migration, true); let state_versions_unique_index_migration = get_unique_index_migration_for_state_versions( @@ -96,7 +96,7 @@ fn extract_table_name(migration: &str) -> String { .to_string() } -fn extract_table_fields(migration: &str) -> Vec { +fn extract_table_fields(migration: &str, remove_json_fields: bool) -> Vec { migration .replace(")", "") .split("(") @@ -104,8 +104,9 @@ fn extract_table_fields(migration: &str) -> Vec { .last() .unwrap() .split(",") - .map(|each_field| { - each_field + .filter(|field| remove_json_fields && !(field.contains("JSON") || field.contains("JSONB"))) + .map(|field| { + field .split_ascii_whitespace() .collect::>() .first() @@ -220,13 +221,13 @@ struct DefaultMigration; impl DefaultMigration { pub fn get() -> String { "state_version_group_id UUID NOT NULL, - contract_address TEXT NOT NULL, + contract_address VARCHAR NOT NULL, chain_id INTEGER NOT NULL, - block_hash TEXT NOT NULL, + block_hash VARCHAR NOT NULL, block_number BIGINT NOT NULL, - transaction_hash TEXT NOT NULL, - transaction_index BIGINT NOT NULL, - log_index BIGINT NOT NULL)" + transaction_hash VARCHAR NOT NULL, + transaction_index INTEGER NOT NULL, + log_index INTEGER NOT NULL)" .to_string() } @@ -287,7 +288,7 @@ mod contract_state_migrations_get_migration_test { #[test] fn returns_two_more_migrations_for_create_state_migrations() { - let contract_state = test_contract_state(); + let contract_state = TestContractState; assert_eq!( contract_state.get_migrations().len(), @@ -297,7 +298,7 @@ mod contract_state_migrations_get_migration_test { #[test] fn appends_default_migration_to_create_state_views_migrations() { - let contract_state = test_contract_state(); + let contract_state = TestContractState; let migrations = contract_state.get_migrations(); let create_state_migration = migrations.first().unwrap(); @@ -311,7 +312,7 @@ mod contract_state_migrations_get_migration_test { #[test] fn removes_repeating_default_migrations_in_create_state_views_migration() { - let contract_state = test_contract_state(); + let contract_state = TestContractState; let migrations = contract_state.get_migrations(); let create_state_migration = migrations.first().unwrap(); @@ -322,7 +323,7 @@ mod contract_state_migrations_get_migration_test { #[test] fn creates_an_extra_migration_for_creating_state_versions() { - let contract_state = test_contract_state(); + let contract_state = TestContractState; let mut migrations = contract_state.get_migrations(); migrations.pop(); let create_state_versions_migration = migrations.last().unwrap(); @@ -333,7 +334,7 @@ mod contract_state_migrations_get_migration_test { #[test] fn normalizes_user_primary_key_column_before_creating_state_versions_migrations() { - let contract_state = test_contract_state_with_primary_key(); + let contract_state = TestContractStateWithPrimaryKey; let mut migrations = contract_state.get_migrations(); migrations.pop(); let create_state_versions_migration = migrations.last().unwrap(); @@ -360,7 +361,7 @@ mod contract_state_migrations_get_migration_test { #[test] fn returns_other_migrations_untouched() { - let contract_state = test_contract_state(); + let contract_state = TestContractState; assert_eq!( contract_state.migrations().last().unwrap(), @@ -368,43 +369,70 @@ mod contract_state_migrations_get_migration_test { ); } - fn test_contract_state() -> impl ContractStateMigrations { - struct TestContractState; + #[test] + fn returns_unique_index_migrations_for_state_versions() { + let contract_state = TestContractState; + let migrations = contract_state.get_migrations(); + + let unique_index_migration = migrations.get(2); + + assert!(unique_index_migration.is_some()); + assert!(unique_index_migration.unwrap().contains("CREATE UNIQUE INDEX IF NOT EXISTS")); + } + + #[test] + fn ignores_json_field_in_unique_index_migration() { + let contract_state = TestContractStateWithJsonField; + let migrations = contract_state.get_migrations(); + + let unique_index_migration = migrations.get(2); + + assert!(!unique_index_migration.unwrap().contains("json_field")); + } - impl ContractStateMigrations for TestContractState { - fn migrations(&self) -> Vec<&'static str> { - vec![ - "CREATE TABLE IF NOT EXISTS nft_states ( + struct TestContractState; + + impl ContractStateMigrations for TestContractState { + fn migrations(&self) -> Vec<&'static str> { + vec![ + "CREATE TABLE IF NOT EXISTS nft_states ( token_id INTEGER NOT NULL, - contract_address TEXT NOT NULL, - owner_address TEXT NOT NULL + contract_address VARCHAR NOT NULL, + owner_address VARCHAR NOT NULL )", - "UPDATE nft_states + "UPDATE nft_states SET owner_address = '' WHERE owner_address IS NULL", - ] - } + ] } - - TestContractState } - fn test_contract_state_with_primary_key() -> impl ContractStateMigrations { - struct TestContractStateWithPrimaryKey; + struct TestContractStateWithPrimaryKey; - impl ContractStateMigrations for TestContractStateWithPrimaryKey { - fn migrations(&self) -> Vec<&'static str> { - vec![ - "CREATE TABLE IF NOT EXISTS nft_states ( + impl ContractStateMigrations for TestContractStateWithPrimaryKey { + fn migrations(&self) -> Vec<&'static str> { + vec![ + "CREATE TABLE IF NOT EXISTS nft_states ( id SERIAL PRIMARY KEY, token_id INTEGER NOT NULL, - contract_address TEXT NOT NULL, - owner_address TEXT NOT NULL + contract_address VARCHAR NOT NULL, + owner_address VARCHAR NOT NULL )", - ] - } + ] } + } - TestContractStateWithPrimaryKey + struct TestContractStateWithJsonField; + + impl ContractStateMigrations for TestContractStateWithJsonField { + fn migrations(&self) -> Vec<&'static str> { + vec![ + "CREATE TABLE IF NOT EXISTS nft_states ( + id SERIAL PRIMARY KEY, + token_id INTEGER NOT NULL, + json_field JSON DEFAULT '{}', + )", + ] + } } } diff --git a/chaindexing/src/diesels/schema.rs b/chaindexing/src/diesels/schema.rs index 3c6e473..fdb5581 100644 --- a/chaindexing/src/diesels/schema.rs +++ b/chaindexing/src/diesels/schema.rs @@ -7,8 +7,8 @@ diesel::table! { next_block_number_to_ingest_from -> Int8, next_block_number_to_handle_from -> Int8, start_block_number -> Int8, - address -> Text, - contract_name -> Text, + address -> VarChar, + contract_name -> VarChar, } } @@ -16,18 +16,18 @@ diesel::table! { chaindexing_events (id) { id -> Uuid, chain_id -> Int4, - contract_address -> Text, - contract_name -> Text, + contract_address -> VarChar, + contract_name -> VarChar, abi -> Text, log_params -> Json, parameters -> Json, topics -> Json, - block_hash -> Text, + block_hash -> VarChar, block_number -> Int8, block_timestamp -> Int8, - transaction_hash -> Text, - transaction_index -> Int8, - log_index -> Int8, + transaction_hash -> VarChar, + transaction_index -> Int4, + log_index -> Int4, removed -> Bool, inserted_at -> Timestamptz, } diff --git a/chaindexing/src/events.rs b/chaindexing/src/events.rs index 7827065..e7f4ba9 100644 --- a/chaindexing/src/events.rs +++ b/chaindexing/src/events.rs @@ -28,8 +28,8 @@ pub struct Event { pub block_number: i64, pub block_timestamp: i64, pub transaction_hash: String, - pub transaction_index: i64, - pub log_index: i64, + pub transaction_index: i32, + pub log_index: i32, removed: bool, inserted_at: chrono::NaiveDateTime, } @@ -92,8 +92,8 @@ impl Event { block_number: log.block_number.unwrap().as_u64() as i64, block_timestamp, transaction_hash: hashes::h256_to_string(&log.transaction_hash.unwrap()).to_lowercase(), - transaction_index: log.transaction_index.unwrap().as_u64() as i64, - log_index: log.log_index.unwrap().as_u64() as i64, + transaction_index: log.transaction_index.unwrap().as_u32() as i32, + log_index: log.log_index.unwrap().as_u32() as i32, removed: log.removed.unwrap(), inserted_at: chrono::Utc::now().naive_utc(), } diff --git a/chaindexing/src/repos/repo.rs b/chaindexing/src/repos/repo.rs index 5a63fa9..28fdd99 100644 --- a/chaindexing/src/repos/repo.rs +++ b/chaindexing/src/repos/repo.rs @@ -193,8 +193,8 @@ impl SQLikeMigrations { &[ "CREATE TABLE IF NOT EXISTS chaindexing_contract_addresses ( id SERIAL PRIMARY KEY, - address TEXT NOT NULL, - contract_name TEXT NOT NULL, + address VARCHAR NOT NULL, + contract_name VARCHAR NOT NULL, chain_id INTEGER NOT NULL, start_block_number BIGINT NOT NULL, next_block_number_to_ingest_from BIGINT NULL, @@ -213,18 +213,18 @@ impl SQLikeMigrations { "CREATE TABLE IF NOT EXISTS chaindexing_events ( id uuid PRIMARY KEY, chain_id INTEGER NOT NULL, - contract_address TEXT NOT NULL, - contract_name TEXT NOT NULL, + contract_address VARCHAR NOT NULL, + contract_name VARCHAR NOT NULL, abi TEXT NOT NULL, log_params JSON NOT NULL, parameters JSON NOT NULL, topics JSON NOT NULL, - block_hash TEXT NOT NULL, + block_hash VARCHAR NOT NULL, block_number BIGINT NOT NULL, block_timestamp BIGINT NOT NULL, - transaction_hash TEXT NOT NULL, - transaction_index BIGINT NOT NULL, - log_index BIGINT NOT NULL, + transaction_hash VARCHAR NOT NULL, + transaction_index INTEGER NOT NULL, + log_index INTEGER NOT NULL, removed BOOLEAN NOT NULL, inserted_at TIMESTAMPTZ NOT NULL DEFAULT NOW() )",