github.com/status-im/status-go@v1.1.0/services/wallet/community/database.go (about)

     1  package community
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/status-im/status-go/services/wallet/thirdparty"
     9  )
    10  
    11  type DataDB struct {
    12  	db *sql.DB
    13  }
    14  
    15  func NewDataDB(sqlDb *sql.DB) *DataDB {
    16  	return &DataDB{
    17  		db: sqlDb,
    18  	}
    19  }
    20  
    21  type InfoState struct {
    22  	LastUpdateTimestamp uint64
    23  	LastUpdateSuccesful bool
    24  }
    25  
    26  const communityInfoColumns = "id, name, color, image, image_payload"
    27  const selectCommunityInfoColumns = "name, color, image, image_payload"
    28  
    29  const communityInfoStateColumns = "id, last_update_timestamp, last_update_successful"
    30  const selectCommunityInfoStateColumns = "last_update_timestamp, last_update_successful"
    31  
    32  func (o *DataDB) SetCommunityInfo(id string, c *thirdparty.CommunityInfo) (err error) {
    33  	tx, err := o.db.Begin()
    34  	if err != nil {
    35  		return err
    36  	}
    37  	defer func() {
    38  		if err == nil {
    39  			err = tx.Commit()
    40  			return
    41  		}
    42  		_ = tx.Rollback()
    43  	}()
    44  
    45  	setState, err := tx.Prepare(fmt.Sprintf(`INSERT OR REPLACE INTO community_data_cache_state (%s) 
    46  		VALUES (?, ?, ?)`, communityInfoStateColumns))
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	valid := c != nil
    52  	_, err = setState.Exec(
    53  		id,
    54  		time.Now().Unix(),
    55  		valid,
    56  	)
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	if valid {
    62  		setInfo, err := tx.Prepare(fmt.Sprintf(`INSERT OR REPLACE INTO community_data_cache (%s) 
    63  			VALUES (?, ?, ?, ?, ?)`, communityInfoColumns))
    64  		if err != nil {
    65  			return err
    66  		}
    67  
    68  		_, err = setInfo.Exec(
    69  			id,
    70  			c.CommunityName,
    71  			c.CommunityColor,
    72  			c.CommunityImage,
    73  			c.CommunityImagePayload,
    74  		)
    75  		if err != nil {
    76  			return err
    77  		}
    78  	}
    79  
    80  	return nil
    81  }
    82  
    83  func (o *DataDB) GetCommunityInfo(id string) (*thirdparty.CommunityInfo, *InfoState, error) {
    84  	if id == "" {
    85  		return nil, nil, nil
    86  	}
    87  
    88  	var info thirdparty.CommunityInfo
    89  	var state InfoState
    90  	var row *sql.Row
    91  
    92  	getState, err := o.db.Prepare(fmt.Sprintf(`SELECT %s
    93  	FROM community_data_cache_state 
    94  	WHERE id=?`, selectCommunityInfoStateColumns))
    95  	if err != nil {
    96  		return nil, nil, err
    97  	}
    98  	row = getState.QueryRow(id)
    99  
   100  	err = row.Scan(
   101  		&state.LastUpdateTimestamp,
   102  		&state.LastUpdateSuccesful,
   103  	)
   104  
   105  	if err == sql.ErrNoRows {
   106  		return nil, nil, nil
   107  	} else if err != nil {
   108  		return nil, nil, err
   109  	}
   110  
   111  	getInfo, err := o.db.Prepare(fmt.Sprintf(`SELECT %s
   112  		FROM community_data_cache
   113  		WHERE id=?`, selectCommunityInfoColumns))
   114  	if err != nil {
   115  		return nil, nil, err
   116  	}
   117  
   118  	row = getInfo.QueryRow(id)
   119  
   120  	err = row.Scan(
   121  		&info.CommunityName,
   122  		&info.CommunityColor,
   123  		&info.CommunityImage,
   124  		&info.CommunityImagePayload,
   125  	)
   126  
   127  	if err == sql.ErrNoRows {
   128  		return nil, &state, nil
   129  	} else if err != nil {
   130  		return nil, nil, err
   131  	}
   132  
   133  	return &info, &state, nil
   134  }