1
votes

This is an extension to this question:

How to increment Cassandra Counter Column with phantom-dsl?

This question has also been asked here.

In Thiagos example the two tables; 'songs' & 'songs_by_artist' both have the same rows but with different partitions (primary keys / clustering columns)

CREATE TABLE test.songs (
    song_id timeuuid PRIMARY KEY,
    album text,
    artist text,
    title text
);

CREATE TABLE test.songs_by_artist (
    artist text,
    song_id timeuuid,
    album text,
    title text,
    PRIMARY KEY (artist, song_id)
) WITH CLUSTERING ORDER BY (song_id ASC);

This means inserting, updating and deleting across both tables within the SongsService works with the same base data / rows.

How would you for example have a table such as 'artist_songs_counts', with columns 'song_id' (K) and 'num_songs' (++) and ensure that 'SongsService' adds corresponding row to each table; 'songs' & 'songs_by_artist' & 'artist_songs_counts' (where there are different numbers of row but information should be linked, such as the artist info).

CREATE TABLE test.artist_songs_counts (
    artist text PRIMARY KEY,
    num_songs counter);
1
@flavian this may be another one for you... - dan-mi-sun

1 Answers

2
votes

SongsService extends ProductionDatabaseProvider that gives to you an object called database where you have access to tables under a certain database:

/**
    * Find songs by Id
    * @param id
    * @return
    */
  def getSongById(id: UUID): Future[Option[Song]] = {
    database.songsModel.getBySongId(id)
  }

Or even better, handling two tables at the same time:

  /**
   * Save a song in both tables
   *
   * @param songs
   * @return
   */
  def saveOrUpdate(songs: Song): Future[ResultSet] = {
    for {
      byId <- database.songsModel.store(songs)
      byArtist <- database.songsByArtistsModel.store(songs)
    } yield byArtist
  }

Since through a database object you can access all tables that belongs to a specific Database, I would implement a counter for artist the following way:

def increment(artist: String): Future[ResultSet] = {
  update
    .where(_.artist eqs artist)
    .modify(_.numSongs += 1)
    .future()
}

Then the saveOrUpdate method could be written as below:

def saveOrUpdate(song: Song): Future[ResultSet] = {
    for {
      byId <- database.songsModel.store(songs)
      byArtist <- database.songsByArtistsModel.store(songs)
      counter <- database.artistSongsCounter.increment(song.artist)
    } yield byArtist
  }