github.com/status-im/status-go@v1.1.0/protocol/persistence_profile_showcase.go (about) 1 package protocol 2 3 import ( 4 "context" 5 "database/sql" 6 "errors" 7 8 "github.com/status-im/status-go/protocol/identity" 9 ) 10 11 // Profile showcase preferences 12 const upsertProfileShowcasePreferencesQuery = "UPDATE profile_showcase_preferences SET clock=? WHERE NOT EXISTS (SELECT 1 FROM profile_showcase_preferences WHERE clock >= ?)" 13 const selectProfileShowcasePreferencesQuery = "SELECT clock FROM profile_showcase_preferences" 14 15 const upsertProfileShowcaseCommunityPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_communities_preferences(community_id, visibility, sort_order) VALUES (?, ?, ?)" // #nosec G101 16 const selectProfileShowcaseCommunityPreferenceQuery = "SELECT community_id, visibility, sort_order FROM profile_showcase_communities_preferences" // #nosec G101 17 const selectSpecifiedShowcaseCommunityPreferenceQuery = "SELECT community_id, visibility, sort_order FROM profile_showcase_communities_preferences WHERE community_id = ?" // #nosec G101 18 const deleteProfileShowcaseCommunityPreferenceQuery = "DELETE FROM profile_showcase_communities_preferences WHERE community_id = ?" // #nosec G101 19 const clearProfileShowcaseCommunitiyPreferencesQuery = "DELETE FROM profile_showcase_communities_preferences" // #nosec G101 20 21 const upsertProfileShowcaseAccountPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_accounts_preferences(address, visibility, sort_order) VALUES (?, ?, ?)" // #nosec G101 22 const selectProfileShowcaseAccountPreferenceQuery = "SELECT address, visibility, sort_order FROM profile_showcase_accounts_preferences" // #nosec G101 23 const selectSpecifiedShowcaseAccountPreferenceQuery = "SELECT address, visibility, sort_order FROM profile_showcase_accounts_preferences WHERE address = ?" // #nosec G101 24 const deleteProfileShowcaseAccountPreferenceQuery = "DELETE FROM profile_showcase_accounts_preferences WHERE address = ?" // #nosec G101 25 const clearProfileShowcaseAccountPreferencesQuery = "DELETE FROM profile_showcase_accounts_preferences" // #nosec G101 26 27 const upsertProfileShowcaseCollectiblePreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_collectibles_preferences(contract_address, chain_id, token_id, visibility, sort_order) VALUES (?, ?, ?, ?, ?)" // #nosec G101 28 const selectProfileShowcaseCollectiblePreferenceQuery = "SELECT contract_address, chain_id, token_id, visibility, sort_order FROM profile_showcase_collectibles_preferences" // #nosec G101 29 const clearProfileShowcaseCollectiblePreferencesQuery = "DELETE FROM profile_showcase_collectibles_preferences" // #nosec G101 30 31 const upsertProfileShowcaseVerifiedTokenPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_verified_tokens_preferences(symbol, visibility, sort_order) VALUES (?, ?, ?)" // #nosec G101 32 const selectProfileShowcaseVerifiedTokenPreferenceQuery = "SELECT symbol, visibility, sort_order FROM profile_showcase_verified_tokens_preferences" // #nosec G101 33 const clearProfileShowcaseVerifiedTokenPreferencesQuery = "DELETE FROM profile_showcase_verified_tokens_preferences" // #nosec G101 34 35 const upsertProfileShowcaseUnverifiedTokenPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_unverified_tokens_preferences(contract_address, chain_id, visibility, sort_order) VALUES (?, ?, ?, ?)" // #nosec G101 36 const selectProfileShowcaseUnverifiedTokenPreferenceQuery = "SELECT contract_address, chain_id, visibility, sort_order FROM profile_showcase_unverified_tokens_preferences" // #nosec G101 37 const clearProfileShowcaseUnverifiedTokenPreferencesQuery = "DELETE FROM profile_showcase_unverified_tokens_preferences" // #nosec G101 38 39 const upsertProfileShowcaseSocialLinkPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_social_links_preferences(url, text, visibility, sort_order) VALUES (?, ?, ?, ?)" // #nosec G101 40 const selectProfileShowcaseSocialLinkPreferenceQuery = "SELECT url, text, visibility, sort_order FROM profile_showcase_social_links_preferences" // #nosec G101 41 const clearProfileShowcaseSocialLinkPreferencesQuery = "DELETE FROM profile_showcase_social_links_preferences" // #nosec G101 42 43 // Profile showcase for a contact 44 const upsertContactProfileShowcaseCommunityQuery = "INSERT OR REPLACE INTO profile_showcase_communities_contacts(contact_id, community_id, sort_order, grant) VALUES (?, ?, ?, ?)" // #nosec G101 45 const selectContactProfileShowcaseCommunityQuery = "SELECT community_id, sort_order, grant FROM profile_showcase_communities_contacts WHERE contact_id = ?" // #nosec G101 46 const removeContactProfileShowcaseCommunityQuery = "DELETE FROM profile_showcase_communities_contacts WHERE contact_id = ?" // #nosec G101 47 48 const upsertContactProfileShowcaseAccountQuery = "INSERT OR REPLACE INTO profile_showcase_accounts_contacts(contact_id, address, name, color_id, emoji, sort_order) VALUES (?, ?, ?, ?, ?, ?)" // #nosec G101 49 const selectContactProfileShowcaseAccountQuery = "SELECT * FROM profile_showcase_accounts_contacts WHERE contact_id = ?" // #nosec G101 50 const removeContactProfileShowcaseAccountQuery = "DELETE FROM profile_showcase_accounts_contacts WHERE contact_id = ?" // #nosec G101 51 52 const upsertContactProfileShowcaseCollectibleQuery = "INSERT OR REPLACE INTO profile_showcase_collectibles_contacts(contact_id, contract_address, chain_id, token_id, sort_order) VALUES (?, ?, ?, ?, ?)" // #nosec G101 53 const selectContactProfileShowcaseCollectibleQuery = "SELECT contract_address, chain_id, token_id, sort_order FROM profile_showcase_collectibles_contacts WHERE contact_id = ?" // #nosec G101 54 const removeContactProfileShowcaseCollectibleQuery = "DELETE FROM profile_showcase_collectibles_contacts WHERE contact_id = ?" // #nosec G101 55 56 const upsertContactProfileShowcaseVerifiedTokenQuery = "INSERT OR REPLACE INTO profile_showcase_verified_tokens_contacts(contact_id, symbol, sort_order) VALUES (?, ?, ?)" // #nosec G101 57 const selectContactProfileShowcaseVerifiedTokenQuery = "SELECT symbol, sort_order FROM profile_showcase_verified_tokens_contacts WHERE contact_id = ?" // #nosec G101 58 const removeContactProfileShowcaseVerifiedTokenQuery = "DELETE FROM profile_showcase_verified_tokens_contacts WHERE contact_id = ?" // #nosec G101 59 60 const upsertContactProfileShowcaseUnverifiedTokenQuery = "INSERT OR REPLACE INTO profile_showcase_unverified_tokens_contacts(contact_id, contract_address, chain_id, sort_order) VALUES (?, ?, ?, ?)" // #nosec G101 61 const selectContactProfileShowcaseUnverifiedTokenQuery = "SELECT contract_address, chain_id, sort_order FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101 62 const removeContactProfileShowcaseUnverifiedTokenQuery = "DELETE FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101 63 64 const upsertContactProfileShowcaseSocialLinkQuery = "INSERT OR REPLACE INTO profile_showcase_social_links_contacts(contact_id, url, text, sort_order) VALUES (?, ?, ?, ?)" // #nosec G101 65 const selectContactProfileShowcaseSocialLinkQuery = "SELECT url, text, sort_order FROM profile_showcase_social_links_contacts WHERE contact_id = ?" // #nosec G101 66 const removeContactProfileShowcaseSocialLinkQuery = "DELETE FROM profile_showcase_social_links_contacts WHERE contact_id = ?" // #nosec G101 67 68 const selectProfileShowcaseAccountsWhichMatchTheAddress = ` 69 SELECT psa.* 70 FROM 71 contacts c 72 LEFT JOIN 73 profile_showcase_accounts_contacts psa 74 ON 75 c.id = psa.contact_id 76 WHERE 77 psa.address = ? 78 ` 79 80 // Queries for the profile showcase preferences 81 82 func (db sqlitePersistence) saveProfileShowcasePreferencesClock(tx *sql.Tx, clock uint64) error { 83 _, err := tx.Exec(upsertProfileShowcasePreferencesQuery, clock, clock) 84 return err 85 } 86 87 func (db sqlitePersistence) getProfileShowcasePreferencesClock(tx *sql.Tx) (uint64, error) { 88 var clock uint64 89 err := tx.QueryRow(selectProfileShowcasePreferencesQuery).Scan(&clock) 90 return clock, err 91 } 92 93 func (db sqlitePersistence) saveProfileShowcaseCommunityPreference(tx *sql.Tx, community *identity.ProfileShowcaseCommunityPreference) error { 94 _, err := tx.Exec(upsertProfileShowcaseCommunityPreferenceQuery, 95 community.CommunityID, 96 community.ShowcaseVisibility, 97 community.Order, 98 ) 99 100 return err 101 } 102 103 func (db sqlitePersistence) processProfileShowcaseCommunityPreferences(rows *sql.Rows) (result []*identity.ProfileShowcaseCommunityPreference, err error) { 104 if rows == nil { 105 return nil, errors.New("rows is nil") 106 } 107 108 for rows.Next() { 109 community := &identity.ProfileShowcaseCommunityPreference{} 110 111 err := rows.Scan( 112 &community.CommunityID, 113 &community.ShowcaseVisibility, 114 &community.Order, 115 ) 116 117 if err != nil { 118 return nil, err 119 } 120 121 result = append(result, community) 122 } 123 124 err = rows.Err() 125 return 126 } 127 128 func (db sqlitePersistence) getProfileShowcaseCommunitiesPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseCommunityPreference, error) { 129 rows, err := tx.Query(selectProfileShowcaseCommunityPreferenceQuery) 130 if err != nil { 131 return nil, err 132 } 133 134 return db.processProfileShowcaseCommunityPreferences(rows) 135 } 136 137 func (db sqlitePersistence) GetProfileShowcaseCommunityPreference(communityID string) (*identity.ProfileShowcaseCommunityPreference, error) { 138 rows, err := db.db.Query(selectSpecifiedShowcaseCommunityPreferenceQuery, communityID) 139 if err != nil { 140 return nil, err 141 } 142 143 communities, err := db.processProfileShowcaseCommunityPreferences(rows) 144 if len(communities) > 0 { 145 return communities[0], err 146 } 147 return nil, err 148 } 149 150 func (db sqlitePersistence) DeleteProfileShowcaseCommunityPreference(communityID string) (bool, error) { 151 result, err := db.db.Exec(deleteProfileShowcaseCommunityPreferenceQuery, communityID) 152 if err != nil { 153 return false, err 154 } 155 156 rows, err := result.RowsAffected() 157 return rows > 0, err 158 } 159 160 func (db sqlitePersistence) clearProfileShowcaseCommunityPreferences(tx *sql.Tx) error { 161 _, err := tx.Exec(clearProfileShowcaseCommunitiyPreferencesQuery) 162 return err 163 } 164 165 func (db sqlitePersistence) saveProfileShowcaseAccountPreference(tx *sql.Tx, account *identity.ProfileShowcaseAccountPreference) error { 166 _, err := tx.Exec(upsertProfileShowcaseAccountPreferenceQuery, 167 account.Address, 168 account.ShowcaseVisibility, 169 account.Order, 170 ) 171 172 return err 173 } 174 175 func (db sqlitePersistence) processProfileShowcaseAccountPreferences(rows *sql.Rows) (result []*identity.ProfileShowcaseAccountPreference, err error) { 176 if rows == nil { 177 return nil, errors.New("rows is nil") 178 } 179 180 for rows.Next() { 181 account := &identity.ProfileShowcaseAccountPreference{} 182 183 err := rows.Scan( 184 &account.Address, 185 &account.ShowcaseVisibility, 186 &account.Order, 187 ) 188 189 if err != nil { 190 return nil, err 191 } 192 193 result = append(result, account) 194 } 195 196 err = rows.Err() 197 return 198 } 199 200 func (db sqlitePersistence) getProfileShowcaseAccountsPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseAccountPreference, error) { 201 rows, err := tx.Query(selectProfileShowcaseAccountPreferenceQuery) 202 if err != nil { 203 return nil, err 204 } 205 206 return db.processProfileShowcaseAccountPreferences(rows) 207 } 208 209 func (db sqlitePersistence) GetProfileShowcaseAccountPreference(accountAddress string) (*identity.ProfileShowcaseAccountPreference, error) { 210 rows, err := db.db.Query(selectSpecifiedShowcaseAccountPreferenceQuery, accountAddress) 211 if err != nil { 212 return nil, err 213 } 214 215 accounts, err := db.processProfileShowcaseAccountPreferences(rows) 216 if len(accounts) > 0 { 217 return accounts[0], err 218 } 219 return nil, err 220 } 221 222 func (db sqlitePersistence) DeleteProfileShowcaseAccountPreference(accountAddress string) (bool, error) { 223 result, err := db.db.Exec(deleteProfileShowcaseAccountPreferenceQuery, accountAddress) 224 if err != nil { 225 return false, err 226 } 227 228 rows, err := result.RowsAffected() 229 return rows > 0, err 230 } 231 232 func (db sqlitePersistence) clearProfileShowcaseAccountPreferences(tx *sql.Tx) error { 233 _, err := tx.Exec(clearProfileShowcaseAccountPreferencesQuery) 234 return err 235 } 236 237 func (db sqlitePersistence) saveProfileShowcaseCollectiblePreference(tx *sql.Tx, collectible *identity.ProfileShowcaseCollectiblePreference) error { 238 _, err := tx.Exec(upsertProfileShowcaseCollectiblePreferenceQuery, 239 collectible.ContractAddress, 240 collectible.ChainID, 241 collectible.TokenID, 242 collectible.ShowcaseVisibility, 243 collectible.Order, 244 ) 245 246 return err 247 } 248 249 func (db sqlitePersistence) getProfileShowcaseCollectiblesPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseCollectiblePreference, error) { 250 rows, err := tx.Query(selectProfileShowcaseCollectiblePreferenceQuery) 251 if err != nil { 252 return nil, err 253 } 254 255 collectibles := []*identity.ProfileShowcaseCollectiblePreference{} 256 257 for rows.Next() { 258 collectible := &identity.ProfileShowcaseCollectiblePreference{} 259 260 err := rows.Scan( 261 &collectible.ContractAddress, 262 &collectible.ChainID, 263 &collectible.TokenID, 264 &collectible.ShowcaseVisibility, 265 &collectible.Order, 266 ) 267 268 if err != nil { 269 return nil, err 270 } 271 272 collectibles = append(collectibles, collectible) 273 } 274 return collectibles, nil 275 } 276 277 func (db sqlitePersistence) clearProfileShowcaseCollectiblePreferences(tx *sql.Tx) error { 278 _, err := tx.Exec(clearProfileShowcaseCollectiblePreferencesQuery) 279 return err 280 } 281 282 func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenPreference(tx *sql.Tx, token *identity.ProfileShowcaseVerifiedTokenPreference) error { 283 _, err := tx.Exec(upsertProfileShowcaseVerifiedTokenPreferenceQuery, 284 token.Symbol, 285 token.ShowcaseVisibility, 286 token.Order, 287 ) 288 289 return err 290 } 291 292 func (db sqlitePersistence) getProfileShowcaseVerifiedTokensPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseVerifiedTokenPreference, error) { 293 rows, err := tx.Query(selectProfileShowcaseVerifiedTokenPreferenceQuery) 294 if err != nil { 295 return nil, err 296 } 297 298 tokens := []*identity.ProfileShowcaseVerifiedTokenPreference{} 299 300 for rows.Next() { 301 token := &identity.ProfileShowcaseVerifiedTokenPreference{} 302 303 err := rows.Scan( 304 &token.Symbol, 305 &token.ShowcaseVisibility, 306 &token.Order, 307 ) 308 309 if err != nil { 310 return nil, err 311 } 312 313 tokens = append(tokens, token) 314 } 315 return tokens, nil 316 } 317 318 func (db sqlitePersistence) clearProfileShowcaseVerifiedTokenPreferences(tx *sql.Tx) error { 319 _, err := tx.Exec(clearProfileShowcaseVerifiedTokenPreferencesQuery) 320 return err 321 } 322 323 func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenPreference(tx *sql.Tx, token *identity.ProfileShowcaseUnverifiedTokenPreference) error { 324 _, err := tx.Exec(upsertProfileShowcaseUnverifiedTokenPreferenceQuery, 325 token.ContractAddress, 326 token.ChainID, 327 token.ShowcaseVisibility, 328 token.Order, 329 ) 330 331 return err 332 } 333 334 func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseUnverifiedTokenPreference, error) { 335 rows, err := tx.Query(selectProfileShowcaseUnverifiedTokenPreferenceQuery) 336 if err != nil { 337 return nil, err 338 } 339 340 tokens := []*identity.ProfileShowcaseUnverifiedTokenPreference{} 341 342 for rows.Next() { 343 token := &identity.ProfileShowcaseUnverifiedTokenPreference{} 344 345 err := rows.Scan( 346 &token.ContractAddress, 347 &token.ChainID, 348 &token.ShowcaseVisibility, 349 &token.Order, 350 ) 351 352 if err != nil { 353 return nil, err 354 } 355 356 tokens = append(tokens, token) 357 } 358 return tokens, nil 359 } 360 361 func (db sqlitePersistence) clearProfileShowcaseUnverifiedTokenPreferences(tx *sql.Tx) error { 362 _, err := tx.Exec(clearProfileShowcaseUnverifiedTokenPreferencesQuery) 363 return err 364 } 365 366 func (db sqlitePersistence) saveProfileShowcaseSocialLinkPreference(tx *sql.Tx, link *identity.ProfileShowcaseSocialLinkPreference) error { 367 _, err := tx.Exec(upsertProfileShowcaseSocialLinkPreferenceQuery, 368 link.URL, 369 link.Text, 370 link.ShowcaseVisibility, 371 link.Order, 372 ) 373 374 return err 375 } 376 377 func (db sqlitePersistence) getProfileShowcaseSocialLinkPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseSocialLinkPreference, error) { 378 rows, err := tx.Query(selectProfileShowcaseSocialLinkPreferenceQuery) 379 if err != nil { 380 return nil, err 381 } 382 383 links := []*identity.ProfileShowcaseSocialLinkPreference{} 384 385 for rows.Next() { 386 link := &identity.ProfileShowcaseSocialLinkPreference{} 387 388 err := rows.Scan( 389 &link.URL, 390 &link.Text, 391 &link.ShowcaseVisibility, 392 &link.Order, 393 ) 394 395 if err != nil { 396 return nil, err 397 } 398 399 links = append(links, link) 400 } 401 return links, nil 402 } 403 404 func (db sqlitePersistence) clearProfileShowcaseSocialLinkPreferences(tx *sql.Tx) error { 405 _, err := tx.Exec(clearProfileShowcaseSocialLinkPreferencesQuery) 406 return err 407 } 408 409 // Queries for the profile showcase for a contact 410 func (db sqlitePersistence) saveProfileShowcaseCommunityContact(tx *sql.Tx, contactID string, community *identity.ProfileShowcaseCommunity) error { 411 _, err := tx.Exec(upsertContactProfileShowcaseCommunityQuery, 412 contactID, 413 community.CommunityID, 414 community.Order, 415 community.Grant, 416 ) 417 418 return err 419 } 420 421 func (db sqlitePersistence) getProfileShowcaseCommunitiesContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseCommunity, error) { 422 rows, err := tx.Query(selectContactProfileShowcaseCommunityQuery, contactID) 423 if err != nil { 424 return nil, err 425 } 426 427 communities := []*identity.ProfileShowcaseCommunity{} 428 429 for rows.Next() { 430 community := &identity.ProfileShowcaseCommunity{ 431 MembershipStatus: identity.ProfileShowcaseMembershipStatusUnproven, 432 } 433 434 err := rows.Scan(&community.CommunityID, &community.Order, &community.Grant) 435 if err != nil { 436 return nil, err 437 } 438 439 communities = append(communities, community) 440 } 441 return communities, nil 442 } 443 444 func (db sqlitePersistence) clearProfileShowcaseCommunityContact(tx *sql.Tx, contactID string) error { 445 _, err := tx.Exec(removeContactProfileShowcaseCommunityQuery, contactID) 446 if err != nil { 447 return err 448 } 449 450 return nil 451 } 452 453 func (db sqlitePersistence) saveProfileShowcaseAccountContact(tx *sql.Tx, contactID string, account *identity.ProfileShowcaseAccount) error { 454 _, err := tx.Exec(upsertContactProfileShowcaseAccountQuery, 455 contactID, 456 account.Address, 457 account.Name, 458 account.ColorID, 459 account.Emoji, 460 account.Order, 461 ) 462 463 return err 464 } 465 466 func (db sqlitePersistence) processProfileShowcaseAccounts(rows *sql.Rows) (result []*identity.ProfileShowcaseAccount, err error) { 467 if rows == nil { 468 return nil, errors.New("rows is nil") 469 } 470 471 for rows.Next() { 472 account := &identity.ProfileShowcaseAccount{} 473 err = rows.Scan(&account.Address, &account.Name, &account.ColorID, &account.Emoji, &account.Order, &account.ContactID) 474 if err != nil { 475 return 476 } 477 478 result = append(result, account) 479 } 480 481 err = rows.Err() 482 return 483 } 484 485 func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseAccount, error) { 486 rows, err := tx.Query(selectContactProfileShowcaseAccountQuery, contactID) 487 if err != nil { 488 return nil, err 489 } 490 491 return db.processProfileShowcaseAccounts(rows) 492 } 493 494 func (db sqlitePersistence) GetProfileShowcaseAccountsByAddress(address string) ([]*identity.ProfileShowcaseAccount, error) { 495 rows, err := db.db.Query(selectProfileShowcaseAccountsWhichMatchTheAddress, address) 496 if err != nil { 497 return nil, err 498 } 499 500 return db.processProfileShowcaseAccounts(rows) 501 } 502 503 func (db sqlitePersistence) clearProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) error { 504 _, err := tx.Exec(removeContactProfileShowcaseAccountQuery, contactID) 505 return err 506 } 507 508 func (db sqlitePersistence) saveProfileShowcaseCollectibleContact(tx *sql.Tx, contactID string, collectible *identity.ProfileShowcaseCollectible) error { 509 _, err := tx.Exec(upsertContactProfileShowcaseCollectibleQuery, 510 contactID, 511 collectible.ContractAddress, 512 collectible.ChainID, 513 collectible.TokenID, 514 collectible.Order, 515 ) 516 517 return err 518 } 519 520 func (db sqlitePersistence) getProfileShowcaseCollectiblesContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseCollectible, error) { 521 rows, err := tx.Query(selectContactProfileShowcaseCollectibleQuery, contactID) 522 if err != nil { 523 return nil, err 524 } 525 526 collectibles := []*identity.ProfileShowcaseCollectible{} 527 528 for rows.Next() { 529 collectible := &identity.ProfileShowcaseCollectible{} 530 531 err := rows.Scan( 532 &collectible.ContractAddress, 533 &collectible.ChainID, 534 &collectible.TokenID, 535 &collectible.Order) 536 if err != nil { 537 return nil, err 538 } 539 540 collectibles = append(collectibles, collectible) 541 } 542 return collectibles, nil 543 } 544 545 func (db sqlitePersistence) clearProfileShowcaseCollectiblesContact(tx *sql.Tx, contactID string) error { 546 _, err := tx.Exec(removeContactProfileShowcaseCollectibleQuery, contactID) 547 return err 548 } 549 550 func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenContact(tx *sql.Tx, contactID string, token *identity.ProfileShowcaseVerifiedToken) error { 551 _, err := tx.Exec(upsertContactProfileShowcaseVerifiedTokenQuery, 552 contactID, 553 token.Symbol, 554 token.Order, 555 ) 556 557 return err 558 } 559 560 func (db sqlitePersistence) getProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseVerifiedToken, error) { 561 rows, err := tx.Query(selectContactProfileShowcaseVerifiedTokenQuery, contactID) 562 if err != nil { 563 return nil, err 564 } 565 566 tokens := []*identity.ProfileShowcaseVerifiedToken{} 567 568 for rows.Next() { 569 token := &identity.ProfileShowcaseVerifiedToken{} 570 571 err := rows.Scan( 572 &token.Symbol, 573 &token.Order) 574 if err != nil { 575 return nil, err 576 } 577 578 tokens = append(tokens, token) 579 } 580 return tokens, nil 581 } 582 583 func (db sqlitePersistence) clearProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) error { 584 _, err := tx.Exec(removeContactProfileShowcaseVerifiedTokenQuery, contactID) 585 return err 586 } 587 588 func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenContact(tx *sql.Tx, contactID string, token *identity.ProfileShowcaseUnverifiedToken) error { 589 _, err := tx.Exec(upsertContactProfileShowcaseUnverifiedTokenQuery, 590 contactID, 591 token.ContractAddress, 592 token.ChainID, 593 token.Order, 594 ) 595 596 return err 597 } 598 599 func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseUnverifiedToken, error) { 600 rows, err := tx.Query(selectContactProfileShowcaseUnverifiedTokenQuery, contactID) 601 if err != nil { 602 return nil, err 603 } 604 605 tokens := []*identity.ProfileShowcaseUnverifiedToken{} 606 607 for rows.Next() { 608 token := &identity.ProfileShowcaseUnverifiedToken{} 609 610 err := rows.Scan( 611 &token.ContractAddress, 612 &token.ChainID, 613 &token.Order) 614 if err != nil { 615 return nil, err 616 } 617 618 tokens = append(tokens, token) 619 } 620 return tokens, nil 621 } 622 623 func (db sqlitePersistence) clearProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) error { 624 _, err := tx.Exec(removeContactProfileShowcaseUnverifiedTokenQuery, contactID) 625 return err 626 } 627 628 func (db sqlitePersistence) saveProfileShowcaseSocialLinkContact(tx *sql.Tx, contactID string, link *identity.ProfileShowcaseSocialLink) error { 629 _, err := tx.Exec(upsertContactProfileShowcaseSocialLinkQuery, 630 contactID, 631 link.URL, 632 link.Text, 633 link.Order, 634 ) 635 636 return err 637 } 638 639 func (db sqlitePersistence) getProfileShowcaseSocialLinksContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseSocialLink, error) { 640 rows, err := tx.Query(selectContactProfileShowcaseSocialLinkQuery, contactID) 641 if err != nil { 642 return nil, err 643 } 644 645 links := []*identity.ProfileShowcaseSocialLink{} 646 647 for rows.Next() { 648 link := &identity.ProfileShowcaseSocialLink{} 649 650 err := rows.Scan( 651 &link.URL, 652 &link.Text, 653 &link.Order) 654 if err != nil { 655 return nil, err 656 } 657 658 links = append(links, link) 659 } 660 err = rows.Err() 661 if err != nil { 662 return nil, err 663 } 664 return links, nil 665 } 666 667 func (db sqlitePersistence) clearProfileShowcaseSocialLinksContact(tx *sql.Tx, contactID string) error { 668 _, err := tx.Exec(removeContactProfileShowcaseSocialLinkQuery, contactID) 669 return err 670 } 671 672 // public functions 673 func (db sqlitePersistence) SaveProfileShowcasePreferences(preferences *identity.ProfileShowcasePreferences) error { 674 tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) 675 if err != nil { 676 return err 677 } 678 defer func() { 679 if err == nil { 680 err = tx.Commit() 681 return 682 } 683 // don't shadow original error 684 _ = tx.Rollback() 685 }() 686 687 err = db.clearProfileShowcaseCommunityPreferences(tx) 688 if err != nil { 689 return err 690 } 691 692 for _, community := range preferences.Communities { 693 err = db.saveProfileShowcaseCommunityPreference(tx, community) 694 if err != nil { 695 return err 696 } 697 } 698 699 err = db.clearProfileShowcaseAccountPreferences(tx) 700 if err != nil { 701 return err 702 } 703 704 for _, account := range preferences.Accounts { 705 err = db.saveProfileShowcaseAccountPreference(tx, account) 706 if err != nil { 707 return err 708 } 709 } 710 711 err = db.clearProfileShowcaseCollectiblePreferences(tx) 712 if err != nil { 713 return err 714 } 715 716 for _, collectible := range preferences.Collectibles { 717 err = db.saveProfileShowcaseCollectiblePreference(tx, collectible) 718 if err != nil { 719 return err 720 } 721 } 722 723 err = db.clearProfileShowcaseVerifiedTokenPreferences(tx) 724 if err != nil { 725 return err 726 } 727 728 for _, token := range preferences.VerifiedTokens { 729 err = db.saveProfileShowcaseVerifiedTokenPreference(tx, token) 730 if err != nil { 731 return err 732 } 733 } 734 735 err = db.clearProfileShowcaseUnverifiedTokenPreferences(tx) 736 if err != nil { 737 return err 738 } 739 740 for _, token := range preferences.UnverifiedTokens { 741 err = db.saveProfileShowcaseUnverifiedTokenPreference(tx, token) 742 if err != nil { 743 return err 744 } 745 } 746 747 err = db.clearProfileShowcaseSocialLinkPreferences(tx) 748 if err != nil { 749 return err 750 } 751 752 for _, link := range preferences.SocialLinks { 753 err = db.saveProfileShowcaseSocialLinkPreference(tx, link) 754 if err != nil { 755 return err 756 } 757 } 758 759 err = db.saveProfileShowcasePreferencesClock(tx, preferences.Clock) 760 if err != nil { 761 return err 762 } 763 764 return nil 765 } 766 767 func (db sqlitePersistence) SaveProfileShowcaseAccountPreference(account *identity.ProfileShowcaseAccountPreference) error { 768 tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) 769 if err != nil { 770 return err 771 } 772 defer func() { 773 if err == nil { 774 err = tx.Commit() 775 return 776 } 777 // don't shadow original error 778 _ = tx.Rollback() 779 }() 780 return db.saveProfileShowcaseAccountPreference(tx, account) 781 } 782 783 func (db sqlitePersistence) GetProfileShowcasePreferences() (*identity.ProfileShowcasePreferences, error) { 784 tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) 785 if err != nil { 786 return nil, err 787 } 788 defer func() { 789 if err == nil { 790 err = tx.Commit() 791 return 792 } 793 // don't shadow original error 794 _ = tx.Rollback() 795 }() 796 797 clock, err := db.getProfileShowcasePreferencesClock(tx) 798 if err != nil { 799 return nil, err 800 } 801 802 communities, err := db.getProfileShowcaseCommunitiesPreferences(tx) 803 if err != nil { 804 return nil, err 805 } 806 807 accounts, err := db.getProfileShowcaseAccountsPreferences(tx) 808 if err != nil { 809 return nil, err 810 } 811 812 collectibles, err := db.getProfileShowcaseCollectiblesPreferences(tx) 813 if err != nil { 814 return nil, err 815 } 816 817 verifiedTokens, err := db.getProfileShowcaseVerifiedTokensPreferences(tx) 818 if err != nil { 819 return nil, err 820 } 821 822 unverifiedTokens, err := db.getProfileShowcaseUnverifiedTokensPreferences(tx) 823 if err != nil { 824 return nil, err 825 } 826 827 socialLinks, err := db.getProfileShowcaseSocialLinkPreferences(tx) 828 if err != nil { 829 return nil, err 830 } 831 832 return &identity.ProfileShowcasePreferences{ 833 Clock: clock, 834 Communities: communities, 835 Accounts: accounts, 836 Collectibles: collectibles, 837 VerifiedTokens: verifiedTokens, 838 UnverifiedTokens: unverifiedTokens, 839 SocialLinks: socialLinks, 840 }, nil 841 } 842 843 func (db sqlitePersistence) SaveProfileShowcaseForContact(showcase *identity.ProfileShowcase) error { 844 tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) 845 if err != nil { 846 return err 847 } 848 defer func() { 849 if err == nil { 850 err = tx.Commit() 851 return 852 } 853 // don't shadow original error 854 _ = tx.Rollback() 855 }() 856 857 for _, community := range showcase.Communities { 858 err = db.saveProfileShowcaseCommunityContact(tx, showcase.ContactID, community) 859 if err != nil { 860 return err 861 } 862 } 863 864 for _, account := range showcase.Accounts { 865 err = db.saveProfileShowcaseAccountContact(tx, showcase.ContactID, account) 866 if err != nil { 867 return err 868 } 869 } 870 871 for _, collectible := range showcase.Collectibles { 872 err = db.saveProfileShowcaseCollectibleContact(tx, showcase.ContactID, collectible) 873 if err != nil { 874 return err 875 } 876 } 877 878 for _, token := range showcase.VerifiedTokens { 879 err = db.saveProfileShowcaseVerifiedTokenContact(tx, showcase.ContactID, token) 880 if err != nil { 881 return err 882 } 883 } 884 885 for _, token := range showcase.UnverifiedTokens { 886 err = db.saveProfileShowcaseUnverifiedTokenContact(tx, showcase.ContactID, token) 887 if err != nil { 888 return err 889 } 890 } 891 892 for _, link := range showcase.SocialLinks { 893 err = db.saveProfileShowcaseSocialLinkContact(tx, showcase.ContactID, link) 894 if err != nil { 895 return err 896 } 897 } 898 899 return nil 900 } 901 902 func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*identity.ProfileShowcase, error) { 903 tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) 904 if err != nil { 905 return nil, err 906 } 907 defer func() { 908 if err == nil { 909 err = tx.Commit() 910 return 911 } 912 // don't shadow original error 913 _ = tx.Rollback() 914 }() 915 916 communities, err := db.getProfileShowcaseCommunitiesContact(tx, contactID) 917 if err != nil { 918 return nil, err 919 } 920 921 accounts, err := db.getProfileShowcaseAccountsContact(tx, contactID) 922 if err != nil { 923 return nil, err 924 } 925 926 collectibles, err := db.getProfileShowcaseCollectiblesContact(tx, contactID) 927 if err != nil { 928 return nil, err 929 } 930 931 verifiedTokens, err := db.getProfileShowcaseVerifiedTokensContact(tx, contactID) 932 if err != nil { 933 return nil, err 934 } 935 936 unverifiedTokens, err := db.getProfileShowcaseUnverifiedTokensContact(tx, contactID) 937 if err != nil { 938 return nil, err 939 } 940 941 socialLinks, err := db.getProfileShowcaseSocialLinksContact(tx, contactID) 942 if err != nil { 943 return nil, err 944 } 945 946 return &identity.ProfileShowcase{ 947 ContactID: contactID, 948 Communities: communities, 949 Accounts: accounts, 950 Collectibles: collectibles, 951 VerifiedTokens: verifiedTokens, 952 UnverifiedTokens: unverifiedTokens, 953 SocialLinks: socialLinks, 954 }, nil 955 } 956 957 func (db sqlitePersistence) ClearProfileShowcaseForContact(contactID string) error { 958 tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{}) 959 if err != nil { 960 return err 961 } 962 defer func() { 963 if err == nil { 964 err = tx.Commit() 965 return 966 } 967 // don't shadow original error 968 _ = tx.Rollback() 969 }() 970 971 err = db.clearProfileShowcaseCommunityContact(tx, contactID) 972 if err != nil { 973 return err 974 } 975 976 err = db.clearProfileShowcaseAccountsContact(tx, contactID) 977 if err != nil { 978 return err 979 } 980 981 err = db.clearProfileShowcaseCollectiblesContact(tx, contactID) 982 if err != nil { 983 return err 984 } 985 986 err = db.clearProfileShowcaseVerifiedTokensContact(tx, contactID) 987 if err != nil { 988 return err 989 } 990 991 err = db.clearProfileShowcaseUnverifiedTokensContact(tx, contactID) 992 if err != nil { 993 return err 994 } 995 996 err = db.clearProfileShowcaseSocialLinksContact(tx, contactID) 997 if err != nil { 998 return err 999 } 1000 1001 return nil 1002 }