bchavez / RethinkDb.Driver

:headphones: A NoSQL C#/.NET RethinkDB database driver with 100% ReQL API coverage.
http://rethinkdb.com/api/java
Other
384 stars 134 forks source link

runResult() on update() does not yield results #20

Closed fiLLLip closed 8 years ago

fiLLLip commented 8 years ago

Don't know if this is a bug or if it is supposed to be like this, but using update() with the trailing runResults() does not yield any results.

var result = _table.get(id).update(new { Target = value }).runResult(connection);
result.Changes.Count > 0; // result is null

var result = _table.get(id).update(new { Target = value }).optArg("return_changes", true).connection);
result.Changes.Count > 0; // returns true or false
bchavez commented 8 years ago

Hi @fiLLLip , what NuGet version are you currently using?

fiLLLip commented 8 years ago

2.2.0-beta-2

bchavez commented 8 years ago

Could you supply the JSON protocol traces associated with the queries? It would really help debug the issue.

fiLLLip commented 8 years ago

Is this what you are looking for? image

fiLLLip commented 8 years ago

I see the problem here. It's not the result that yields null, but result.Changes... result.replaced returns 1 :smile: Closing this :+1:

bchavez commented 8 years ago

Hey @fiLLLip ,

I wrote a quick example:

[Test]
public void issue_20()
{
    var table = r.db(DbName).table(TableName);
    table.delete().run(conn);

    Console.WriteLine("INSERT");
    var result = table.insert(new {foo = "bar"}).runResult(conn);
    var id = result.GeneratedKeys[0];
    result.AssertInserted(1);

    Console.WriteLine("UPDATE 1 / VALUE 1");
    var value = "VALUE1";
    result = table.get(id).update(new {Target = value}).runResult(conn);
    result.Dump();

    Console.WriteLine("UPDATE 2 / VALUE 2");
    value = "VALUE2";
    var optResult = table.get(id).update(new {Target = value})
        .optArg("return_changes", true).run(conn);
    ExtensionsForTesting.Dump(optResult);
}

The full JSON trace I got back for the example above is:

INSERT
TRACE JSON Send: Token: 4, JSON: [1,[56,[[15,[[14,["query"]],"test"]],{"foo":"bar"}]],{}]
TRACE JSON Recv: Token: 4, JSON: {"t":1,"r":[{"deleted":0,"errors":0,"generated_keys":["d6180360-e9b6-4403-be3b-234af9458fe0"],"inserted":1,"replaced":0,"skipped":0,"unchanged":0}]}
UPDATE 1 / VALUE 1
TRACE JSON Send: Token: 5, JSON: [1,[53,[[16,[[15,[[14,["query"]],"test"]],"d6180360-e9b6-4403-be3b-234af9458fe0"]],{"Target":"VALUE1"}]],{}]
TRACE JSON Recv: Token: 5, JSON: {"t":1,"r":[{"deleted":0,"errors":0,"inserted":0,"replaced":1,"skipped":0,"unchanged":0}]}
{
  "generated_keys": null,
  "Inserted": 0,
  "Replaced": 1,
  "Unchanged": 0,
  "Errors": 0,
  "first_error": null,
  "Deleted": 0,
  "Skipped": 0,
  "Warnings": null,
  "Changes": null,
  "Ready": null,
  "dbs_created": 0,
  "dbs_dropped": 0,
  "tables_created": 0,
  "tables_dropped": 0
}
UPDATE 2 / VALUE 2
TRACE JSON Send: Token: 6, JSON: [1,[53,[[16,[[15,[[14,["query"]],"test"]],"d6180360-e9b6-4403-be3b-234af9458fe0"]],{"Target":"VALUE2"}],{"return_changes":true}],{}]
TRACE JSON Recv: Token: 6, JSON: {"t":1,"r":[{"changes":[{"new_val":{"Target":"VALUE2","foo":"bar","id":"d6180360-e9b6-4403-be3b-234af9458fe0"},"old_val":{"Target":"VALUE1","foo":"bar","id":"d6180360-e9b6-4403-be3b-234af9458fe0"}}],"deleted":0,"errors":0,"inserted":0,"replaced":1,"skipped":0,"unchanged":0}]}
{
  "changes": [
    {
      "new_val": {
        "Target": "VALUE2",
        "foo": "bar",
        "id": "d6180360-e9b6-4403-be3b-234af9458fe0"
      },
      "old_val": {
        "Target": "VALUE1",
        "foo": "bar",
        "id": "d6180360-e9b6-4403-be3b-234af9458fe0"
      }
    }
  ],
  "deleted": 0,
  "errors": 0,
  "inserted": 0,
  "replaced": 1,
  "skipped": 0,
  "unchanged": 0
}

Query 1

UPDATE 1 query:

    result = table.get(id).update(new {Target = value}).runResult(conn);

we got back a response:

 {"t":1,"r":[{"deleted":0,"errors":0,"inserted":0,"replaced":1,"skipped":0,"unchanged":0}]}

There is no Changes key to parse, so it's null in Result.

Query 2

UPDATE 2 query:

var optResult = table.get(id).update(new {Target = value})
        .optArg("return_changes", true).run(conn);
{"t":1,"r":[{"changes":[{"new_val":{"Target":"VALUE2","foo":"bar","id":"d6180360-e9b6-4403-be3b-234af9458fe0"},"old_val":{"Target":"VALUE1","foo":"bar","id":"d6180360-e9b6-4403-be3b-234af9458fe0"}}],"deleted":0,"errors":0,"inserted":0,"replaced":1,"skipped":0,"unchanged":0}]}

Now there is a Changes key to parse and populate Result.Changes. I think this is the expected behavior? Do you think there's a better way to handle this?

bchavez commented 8 years ago

Okay, great! Glad you found the problem :) :+1:

fiLLLip commented 8 years ago

I obviously didn't need the changes, but just an indication that something changed! Thanks for the write up :smile: