1

I've been reading http://godoc.org/github.com/gocql/gocql Yet I don't understand how to do INSERT -- IF NOT EXIST with gocql.
It stated that

func (*Query) ScanCAS

func (q *Query) ScanCAS(dest ...interface{}) (applied bool, err error)

ScanCAS executes a lightweight transaction (i.e. an UPDATE or INSERT statement containing an IF clause). If the transaction fails because the existing values did not match, the previous values will be stored in dest.

When I run

cluster := gocql.NewCluster("127.0.0.1")
cluster.Keyspace = "example"
cluster.Consistency = gocql.Quorum
session, _ := cluster.CreateSession()
defer session.Close()

var mapQ map[string]interface{}
var inserted bool
var id gocql.UUID
var timeline, text string
// insert a tweet
isTrue, err := session.Query(`INSERT INTO tweet (timeline, id, text) VALUES (?, ?, ?) IF NOT EXIST`,
    "hermano", gocql.TimeUUID(), "good night").
    ScanCAS(); if err != nil {
    log.Println(err)
}
fmt.Println(timeline, id, text)
fmt.Printf("%+v\n", isTrue)
fmt.Printf("%+v\n", inserted)
fmt.Printf("%+v\n", mapQ)

I get:
Failed parsing statement: [INSERT INTO tweet (timeline, id, text) VALUES (?, ?, ?) IF NOT EXIST] reason: ArrayIndexOutOfBoundsException -1

So my question is:
1. How to actually do INSERT IF NOT EXIST in gocql? Can you guys give me any example?
2. How to do proper ScanCAS?
3. What makes MapScanCAS and ScanCAS different? I don't understand what column mismatching are the author is talking about
4. Are there any good page that explains gocql beside its godoc page?

Joni Atif
  • 61
  • 1
  • 2
  • 6
  • 1
    The correct syntax is ``INSERT IF NOT EXISTS`` ( S at the end) – Mikhail Stepura Nov 10 '14 at 18:00
  • Well, that is embarassing. Thank you for the correction. It doesn't have any error now. But do you happen to know how can this works when ScanCAS doesn't have any argument? I still can't understand the correct way of using ScanCAS, because I thought I would be more like Scan – Joni Atif Nov 10 '14 at 19:01
  • If the `INSERT` didn't insert a new row because one already existed, the `dest` argument will be filled in with the data from the row that already existed. The "column mismatching" is something to do with gocql not being able to control the order the columns come back in, and so struct unmarshalling not working properly, so `MapScanCAS` returns the data in a map instead. – hobbs Feb 03 '16 at 04:45

2 Answers2

1

My understanding:

How to actually do INSERT IF NOT EXIST in gocql? Can you guys give me any example?

Since the LWT you are executing needs to read data from Cassandra first and decide if the value should be inserted/updated, ScanCAS will return 1) whether the change of this LWT is applied, 2) if not applied, ScanCAS will return the existing value(s) in Cassandra. So in ScanCAS you should try to read the same type of data you are inserting.

How to do proper ScanCAS?

Similar to question 1.

What makes MapScanCAS and ScanCAS different? I don't understand what column mismatching are the author is talking about

I think the author means that it is easy to mess up the order of scanning the returned values/columns, so you could use MapScanCAS to avoid this issue

Noel Widmer
  • 4,444
  • 9
  • 45
  • 69
Ertai Duo
  • 11
  • 3
0

looks like a typo, you should use "IF NOT EXISTS"

user3562417
  • 256
  • 2
  • 4