# db8 Luna Send Examples

luna-send is a command line tool you can use in a shell on the device to make calls to service components such as db8 (com.palm.db).

The following are provided to give you additional examples of making db8 service API calls.

Before You Begin

To test out these calls yourself, you need two things:

1. A USB cord for connecting the device to your development PC.

2. A mechanism for logging into your device. The Tools section describes various mechanisms for doing this. Other options include using novaterm on the Mac.

App Impersonation

Using many of these calls at the command line may require you to impersonate the db8 kind owner. Normally, only the owner has permission to perform most database operations. This involves using the `-a` luna-send option.

For example:

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.defaults:1"}]}'

If you get a `"db:permission denied"` error, then try using this option. See Allowing Other Apps or Services to Access Your db8 Data for more information on permissions.

## API calls

- batch
- del
- delKind
- find
- get
- merge
- put
- putKind
- search
- watch

Other operations:

- collate
- revision sets

See also:

- Javascript Wrapper API - API calls provided with the JavaScript Foundation libraries to interface with the db8 service.
- Using serviceRequest - Call the db8 service using the "serviceRequest" API.

## batch

In one batch, put an object, delete by id and do a query - responses will be in the same order as the requested operations

    luna-send -n 1 luna://com.palm.db/batch '{"operations":[{"method":"put","params":{"objects":[{"_kind":"com.palm.test:1","foo":12}]}},{"method":"del","params":{"ids":[3]}},{"method":"find","params":{"query":{"from":"com.palm.test:1"}}}]}'

    {"returnValue":true,"responses":[{"returnValue":true,"results":[{"id":8,"rev":8}]},{"returnValue":true,"count":1},{"returnValue":true,"results":[{"_id":8,"_kind":"com.palm.test:1","_rev":8,"foo":12}]}]}

## del

Delete an object

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/del '{"ids":["2+7c"]}'
    {"returnValue":true,"results":[{"id":"2+7c","rev":554}]}

Query again, and the deleted object is not present

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"=","val":1}]}}'
    {"returnValue":true,"results":[{"_id":3,"_rev":3,"_kind":"com.palm.test:1","bar":1000,"foo":1}]}

Delete with query

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/del '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"=","val":1}]}}'
    {"returnValue":true,"count":2}

Verify that objects were deleted

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"=","val":1}]}}'
    {"returnValue":true,"results":[]}

## delKind

Delete a kind object

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/delKind '{"id":"com.palm.test:1"}'
    {"returnValue":true}

Verify that the kind is no longer registered

    luna-send -n 1 luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"=","val":1}]}}'
    {"errorCode":-3976,"errorText":"kind not registered: 'com.palm.test:1'","returnValue":false}

## find

Simple query

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"=","val":1}]}}'
     {"returnValue":true,"results":[{"_id":"++HGVOxufaCYXCLj","_kind":"com.palm.test:1","_rev":8506,"bar":1000,"foo":1},{"_id":"++HGVPGVsSC5i6qw","_kind":"com.palm.test:1","_rev":8507,"bar":1000,"foo":1}]}

Query on multiple properties

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"bar","op":"=","val":1000},{"prop":"foo","op":">","val":1}]}}'
    {"returnValue":true,"results":[{"_id":4,"_rev":4,"_kind":"com.palm.test:1","bar":1000,"foo":2},{"_id":5,"_rev":5,"_kind":"com.palm.test:1","bar":1000,"foo":3},{"_id":6,"_rev":6,"_kind":"com.palm.test:1","bar":1000,"foo":4}]}

Put two objects with shared prefix (and one without)

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.test:1","foo":1,"bar":1000},{"_kind":"com.palm.test:1","foo":"hello"},{"_kind":"com.palm.test:1","foo":"hello world!"},{"_kind":"com.palm.test:1","foo":"goodbye"}]}'
    {"returnValue":true,"results":[{"id":8,"rev":8},{"id":9,"rev":9},{"id":10,"rev":10},{"id":11,"rev":11}]}

Prefix query

    luna-send -n 1 luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}]}}'
    {"returnValue":true,"results":[{"id":"++HGVUotjT08QQac","rev":8511},{"id":"++HGVUotkvSmDLn0","rev":8512},{"id":"++HGVUotm2wzr3la","rev":8513},{"id":"++HGVUotn00Bxwib","rev":8514}]}

Query with a watch

    luna-send -n 2 -a luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}]},"watch":true}'
     {"returnValue":true,"results":[{"_id":55,"_rev":55,"_kind":"com.palm.test:1","foo":"hello"},{"_id":56,"_rev":56,"_kind":"com.palm.test:1","foo":"hello world!"}]}

After an update which would change the results of the query, you get another response:

    {"returnValue":true,"fired":true}

Query with a limit

    luna-send -n 1 luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}],"limit":1}}'
     {"returnValue":true,"results":[{"_id":"++HGVUotkvSmDLn0","_kind":"com.palm.test:1","_rev":8512,"foo":"hello"}],"next":"2+CN05W_Q5lj++Ff9oW6K_KjS5hqJqp3I5sk+F"}

Get the next page of results

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}],"limit":1,"page":"2+CN05W_Q5lj++Ff9oW6K_KjS5hqJqp3I5sk+F"}}'

    {"returnValue":true,"results":[{"_id":"++HGVUotm2wzr3la","_kind":"com.palm.test:1","_rev":8513,"foo":"hello world!"}],"next":"2+CN05W_Q5lj76SjRalZ7F+39mh7GpOKQrGhBbSuRYCgNF3"}

Count the results that would have been return without the limit

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}],"limit":1},"count":true}'
    {"returnValue":true,"results":[{"_id":"++HGVUotkvSmDLn0","_kind":"com.palm.test:1","_rev":8512,"foo":"hello"}],"next":"2+CN05W_Q5lj++Ff9oW6K_KjS5hqJqp3I5sk+F","count":2}

## get

Get a single object

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGVPGVv44P7g1P"]}'
    {"returnValue":true,"results":[{"_id":"++HGVPGVv44P7g1P","_kind":"com.palm.test:1","_rev":8509,"bar":1000,"foo":3}]}

Get an array of objects

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGVPGVsSC5i6qw","++HGVPGVv44P7g1P","++HGVPGVw8g7_lrA"]}'
     {"returnValue":true,"results":[{"_id":"++HGVPGVsSC5i6qw","_kind":"com.palm.test:1","_rev":8507,"bar":1000,"foo":1},{"_id":"++HGVPGVv44P7g1P","_kind":"com.palm.test:1","_rev":8509,"bar":1000,"foo":3},{"_id":"++HGVPGVw8g7_lrA","_kind":"com.palm.test:1","_rev":8510,"bar":1000,"foo":4}]}

## merge

Merge array of objects

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/merge '{"objects":[{"_id":"++HGVPGVsSC5i6qw","bar":5000},{"_id":"++HGVPGVv44P7g1P","bar":6000}]}'
    {"returnValue":true,"results":[{"id":"++HGVPGVsSC5i6qw","rev":8516},{"id":"++HGVPGVv44P7g1P","rev":8517}]}

Verify that props were merged

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGVPGVsSC5i6qw","++HGVPGVv44P7g1P"]}'
    {"returnValue":true,"results":[{"_id":"++HGVPGVsSC5i6qw","_kind":"com.palm.test:1","_rev":8516,"bar":5000,"foo":1},{"_id":"++HGVPGVv44P7g1P","_kind":"com.palm.test:1","_rev":8517,"bar":6000,"foo":3}]}

Merge with query

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/merge '{"props":{"bar":null},"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}]}}'
    {"returnValue":true,"count":2}

Verify that props were merged

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGVUotm2wzr3la","++HGVUotkvSmDLn0"]}'
    {"returnValue":true,"results": [{"_id":"++HGVUotm2wzr3la", "_kind":"com.palm.test:1", "_rev":8519,"bar":null,"foo":"hello world!"}, {"_id":"++HGVUotkvSmDLn0", "_kind":"com.palm.test:1",  "_rev":8518,"bar":null, "foo":"hello"}]}

Merging arrays

Merging an existing object: {"a":[1,2,3]} with object: {"a":[4,5,6]} results in {"a":[4,5,6]}

Put an object with an array

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.test:1","a":[1,2,3]}]}'
    {"returnValue":true,"results":[{"id":"++HGVhDI0DNjiBWJ","rev":8520}]}

Merge with another object containing an array - note the response now contains id and rev

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/merge '{"objects":[{"_id":"++HGVhDI0DNjiBWJ","a":[4,5,6]}]}'
    {"returnValue":true,"results":[{"id":"++HGVhDI0DNjiBWJ","rev":8522}]}

Retrieve the merged object - note the array was overwritten

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGVhDI0DNjiBWJ"]}'
    {"returnValue":true,"results":[{"_id":"++HGVhDI0DNjiBWJ","_kind":"com.palm.test:1","_rev":8522,"a":[4,5,6]}]}

## put

Put a single object

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.test:1","foo":1,"bar":1000}]}'
    {"returnValue":true,"results":[{"id":"++HGVOxufaCYXCLj","rev":8506}]}

Put an array of objects

    luna-send -n 1 luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.test:1","foo":1,"bar":1000},{"_kind":"com.palm.test:1","foo":2,"bar":1000},{"_kind":"com.palm.test:1","foo":3,"bar":1000},{"_kind":"com.palm.test:1","foo":4,"bar":1000}]}'
     {"returnValue":true,"results":[{"id":"++HGVPGVsSC5i6qw","rev":8507},{"id":"++HGVPGVtw_DGF44","rev":8508},{"id":"++HGVPGVv44P7g1P","rev":8509},{"id":"++HGVPGVw8g7_lrA","rev":8510}]}

## putKind

Basic kind

Register the type "com.palm.test:1"

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/putKind '{"id":"com.palm.test:1","owner":"com.palm.contacts","indexes":[{"name":"foo", "props":[{"name":"foo"}]},{"name":"barfoo","props":[{"name":"bar"},{"name":"foo"}]}]}]}'
    {"returnValue":true}

Kind with default values

Register the type "com.palm.defaults:1" with a default value

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/putKind '{"id":"com.palm.defaults:1","owner":"com.palm.contacts","indexes":[{"name":"foo","props":[{"name":"foo", "default":1}]}]}'
    {"returnValue":true}

Put an object of type "com.palm.defaults:1" without the foo property

    luna-send -n 1 luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.defaults:1"}]}'
    {"returnValue":true,"results":[{"id":3,"rev":3}]}

Query for "com.palm.defaults:1" using the foo index - the object we just put should be found since we provided a default value for foo.

    luna-send -n 1 luna://com.palm.db/find '{"query":{"from":"com.palm.defaults:1", "where":{"prop":"foo","op":">=","val":0}}}'
     {"returnValue":true,"results":[{"_id":3,"_kind":"com.palm.defaults:1","_rev":3}]}

Kind that extends another kind

Register the parent kind "com.palm.parent:1"

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/putKind '{"id":"com.palm.parent:1","owner":"com.palm.contacts","indexes":[{"name":"foo","props":[{"name":"foo"}]}]}'
    {"returnValue":true}

Register the child kind "com.palm.child:1"

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/putKind '{"id":"com.palm.child:1","owner":"com.palm.contacts","extends":["com.palm.parent:1"]}'
    {"returnValue":true}

Add an object of the child kind

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.child:1", "foo":1}]}'
    {"returnValue":true,"results":[{"id":"1kZ","rev":9}]}

Query on the parent kind - you will get child objects

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.parent:1","where":[{"prop":"foo","op":"=","val":1}]}}'
    {"returnValue":true,"results":[{"_id":"1kZ","_kind":"com.palm.child:1","_rev":9,"foo":1}]}

## search

Register kind with tokenized, primary collated index on foo

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/putKind '{"id":"com.palm.searchtest:1","owner":"com.palm.contacts","indexes":[{"name":"bar","props":[{"name":"bar","collate":"primary","tokenize":"default"}]}]}'
    {"returnValue":true}

Put a few objects

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.searchtest:1","foo":"four score and seven years ago", "bar":"barbar"},{"_kind":"com.palm.searchtest:1","foo":"FOUR BOTTLES OF BEER!!!!", "bar":"jarjar"},{"_kind":"com.palm.searchtest:1","foo":"seven dwarves", "bar":"woohoo"},{"_kind":"com.palm.searchtest:1","foo":"fast and furious", "bar":"myBar"}]}'
    {"returnValue":true,"results":[{"id":"1nF","rev":52},{"id":"1nJ","rev":53},{"id":"1nN","rev":54},{"id":"1nR","rev":55}]}

Search on 'fo'

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/search '{"query":{"from":"com.palm.searchtest:1","orderBy":"foo","where":[{"prop":"foo","op":"?","val":"fo","collate":"primary"}]}}'
    {"returnValue":true,"results":[{"_id":"1nZ","_kind":"com.palm.searchtest:1","_rev":57,"foo":"FOUR BOTTLES OF BEER!!!!"},{"_id":"1nF","_kind":"com.palm.searchtest:1","_rev":52,"foo":"four score and seven years ago"}],"count":3}

Search on 'fa an fu'

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/search '{"query":{"from":"com.palm.searchtest:1","orderBy":"foo","where":[{"prop":"foo","op":"?","val":"fa an fu","collate":"primary"}]}}'
    {"returnValue":true,"results":[{"_id":"1ng","_kind":"com.palm.searchtest:1","_rev":59,"foo":"fast and furious"}],"count":1}

## watch

    luna-send -n 2 -a com.palm.contacts luna://com.palm.db/watch '{"query":{"from":"com.palm.test:1","where":[{"prop":"foo","op":"%","val":"hello"}]}}'

The following is returned if there are no results that match the query

    {"returnValue":true}

The following is returned if there are results that match the query

    {"returnValue":true,"fired":true}

After an update happens which would change the response, you get another response:

    {"returnValue":true,"fired":true}

## collate

Register kind with collation type of primary on the property foo

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/putKind '{"id":"com.palm.colltest:1","owner":"com.palm.contacts","indexes":[{"name":"foo","props":[{"name":"foo","collate":"primary"}]}]}'
    {"returnValue":true}

Put objects with mixed case foo values

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.colltest:1","foo":"aardvark"},{"_kind":"com.palm.colltest:1","foo":"APPLE"},{"_kind":"com.palm.colltest:1","foo":"ball"},{"_kind":"com.palm.colltest:1","foo":"Boy"},]}'
    {"returnValue":true,"results":[{"id":"++HGVp3etqlwJBYm","rev":8525},{"id":"++HGVp3evwKcmrh2","rev":8526},{"id":"++HGVp3ex+xr00M+","rev":8527},{"id":"++HGVp3exztxrUAt","rev":8528}]}

Order by foo

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.colltest:1","orderBy":"foo"}}'
    {"returnValue":true,"results":[ {"_id":"++HGVp3etqlwJBYm", "_kind":"com.palm.colltest:1", "_rev":8525,"foo":"aardvark"}, {"_id":"++HGVp3evwKcmrh2", "_kind":"com.palm.colltest:1", "_rev":8526,"foo":"APPLE"},{"_id":"++HGVp3ex+xr00M+", "_kind":"com.palm.colltest:1", "_rev":8527,"foo":"ball"}, {"_id":"++HGVp3exztxrUAt", "_kind":"com.palm.colltest:1", "_rev":8528,"foo":"Boy"}]}

Prefix match with primary collation

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/find '{"query":{"from":"com.palm.colltest:1","where":[{"prop":"foo","op":"%","val":"a","collate":"primary"}]}}'
      {"returnValue":true,"results":[{"_id":"++HGVp3etqlwJBYm","_kind":"com.palm.colltest:1","_rev":8525,"foo":"aardvark"},{"_id":"++HGVp3evwKcmrh2","_kind":"com.palm.colltest:1","_rev":8526,"foo":"APPLE"}]}

## revision set

Put kind with a revset on the properties foo and bar

    luna-send -n 1 luna://com.palm.db/putKind '{"id":"com.palm.revtest:1","owner":"com.palm.contacts","indexes":[{"name":"fooBarRev", "props":[{"name":"fooBarRev"}]}],"revSets":[{"name":"fooBarRev", "props":[{"name":"foo"},{"name":"bar"}]}]}'
    {"returnValue":true}

fooBarRev is assigned to current rev whenever foo or bar is updated

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/put '{"objects":[{"_kind":"com.palm.revtest:1","foo":1,"bar":2}]}'
    {"returnValue":true,"results":[{"id":"++HGZTDaQgxxoEaG"","rev":8852}]}}

Get fooBarRev value after put

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGZTDaQgxxoEaG"]}'
     {"returnValue":true,"results":[{"_id":"++HGZTDaQgxxoEaG","_kind":"com.palm.revtest:1","_rev":8852,"bar":2,"foo":1,"fooBarRev":8852}]}

Update foo, fooBarRev updated to current rev

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/merge '{"objects":[{"_id":"++HGZTDaQgxxoEaG","foo":2}]}'
    {"returnValue":true,"results":[{"id":"++HGZTDaQgxxoEaG","rev":8853}]}

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGZTDaQgxxoEaG"]}'
     {"returnValue":true,"results":[{"_id":"++HGZTDaQgxxoEaG", "_kind":"com.palm.revtest:1", "_rev":8853, "bar":2,"foo":2, "fooBarRev":8853}]}

Update property ("baz") not in rev set, fooBarRev not updated to current rev

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/merge '{"objects":[{"_id":"++HGZTDaQgxxoEaG","baz":2}]}'
    {"returnValue":true,"results":[{"id":"++HGZTDaQgxxoEaG","rev":8854}]}

    luna-send -n 1 -a com.palm.contacts luna://com.palm.db/get '{"ids":["++HGZTDaQgxxoEaG"]}'
    {"returnValue":true,"results":[{"_id":"++HGZTDaQgxxoEaG", "_kind":"com.palm.revtest:1", "_rev":8854,"bar":2, "baz":2,"foo":2,"fooBarRev":8853}]}