Skip to content

Run Helpers

Brian Chavez edited this page Apr 20, 2016 · 30 revisions

The official RethinkDB drivers expect developers to know the type of response returned from a given query. The C# driver and official Java driver follow the same paradigm.

In order for the C# driver to maintain API compatibility with the official drivers, the .Run() method return a dynamic type. The underlying dynamic type is determined by Newtonsoft and represents a best effort guess as to what the underlying type is. The Dynamic Language Runtime (DLR) Integration goes into further detail.

There are two consequences to using the .Run() method:

  1. The execution context of .Run() goes through the DLR. The DLR incurs a slight performance tax.
  2. An extra syntax burden is placed on the developer to get a strongly-typed result from .Run().

The use of run helpers solve both issues above. To illustrate, consider the following example:

Cursor<Change<Hero>> changeFeed = R.Db("marvel").Table("heros")
                                   .Changes().Run<Cursor<Change<Foo>>();

The syntax is a bit verbose and it invokes the DLR via .Run<T>(). The above query can be written more simply (and gain a slight edge in performance) by using the .RunChanges helper as shown below:

var changeFeed = R.Db("marvel").Table("heros")
                  .Changes().RunChanges<Hero>();

The full list of Run Helpers are outlined here:


.RunAtom

When the response type for a query is a SUCCESS_ATOM the driver is expected to return an object of T. Typically, queries that return singleRowSelection are atom responses.

Hero result = R.Db("marvel").Table("heros")
              .Get("iron_man")
              .Run<Hero>(conn);

var result = R.Db("marvel").Table("heros")
              .Get("iron_man")
              .RunAtom<Hero>(conn);

.RunCursor

When the response type for a query is a SUCCESS_SEQUENCE or SUCCESS_PARTIAL the driver is expected to return a cursor.

Cursor<Hero> all = R.Db("marvel")
                    .Table("heros")
                    .GetAll("iron_man", "hulk", "thor")
                    .Run<Hero>(conn);

var all = R.Db("marvel")
           .Table("heros")
           .GetAll("iron_man", "hulk", "thor")
           .RunCursor<Hero>(conn);

.RunResult<T>

.RunResult<T>() helps deserialize T object atom (SUCCESS_ATOM) or finished sequences List<T> (SUCCESS_SEQUENCE) List<T> server responses.


.RunResult DML

.RunResult() helps with DML type of result queries:

var result = R.Db("marvel").Table("heros")
              .Insert({"name":"Iron Man"})
              .RunResult(conn);
/*
{
    "deleted": 0,
    "errors": 0,
    "inserted": 1,
    "replaced": 0,
    "skipped": 0,
    "unchanged": 0
}
*/

In the example above, result is a strongly typed Result helper type with strongly typed properties.

Result Assertions

With Result types, assertions can be made about the result. For example:

var result = R.Db("marvel").Table("heros")
              .Insert({"name":"Iron Man"})
              .RunResult(conn)
              .AssertNoErrors()
              .AssertInserted(1);

The example above ensures that there are 0 errors and 1 document inserted. Otherwise an exception is thrown.


.RunChanges<T>()

Change feed declaraitons can be combersome with a dynamic .Run(). For exmaple,

Cursor<Change<Hero>> changeFeed = R.Db("marvel").Table("heros")
                                   .Changes().Run<Cursor<Change<Foo>>();

Using the RunChanges<T> helper reduces verbosity while type safety for changeFeed is preserved as Cursor<Change<Hero>>:

var changeFeed = R.Db("marvel").Table("heros")
                  .Changes().RunChanges<Hero>();

Change<T> is a helper type that contains two properties, NewValue and OldValue of type T. When subscribing to .Changes() the changeFeed cursor will fill with Change<T> items when the changeFeed cursor is enumerated over and as changes happen.


.runGrouping<TKey,TItem>()

Consider the following query:

IEnumerable<GroupedResult<string,Game>> result = 
    R.Expr(games).Group("player")
     .Run<GroupedResult<string, Game>>(conn);

foreach( var group in result )
{
    Console.WriteLine($">>>> KEY:{group.Key}");
    group.Dump();
}

The same query can be simplified with the RunGrouping helper:

var result = 
    R.Expr(games).Group("player")
     .RunGrouping<string, Game>(conn);

foreach( var group in result )
{
    Console.WriteLine($">>>> KEY:{group.Key}");
    group.Dump();
}

result is still typed as IEnumerable<GroupedResult<string,Game>>.

Clone this wiki locally