Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_ts is not returned by upsertDocument or replaceDocument #33

Open
graham-sportsmgmt opened this issue Aug 22, 2018 · 9 comments
Open

_ts is not returned by upsertDocument or replaceDocument #33

graham-sportsmgmt opened this issue Aug 22, 2018 · 9 comments

Comments

@graham-sportsmgmt
Copy link

I have written a Stored Procedure to do a partial Document update and I want to return only the _ts attribute in order for subsequent queries to use this as a parameter.

This was tested in the Azure Portal Data Explorer and using the node.js sdk, both had the same result.

Whether I use upsertDocument or replaceDocument these are the only four system attributes returned in the RequestCallback.resource:

"_rid": "0eUiAJMAdQDl9QAAAAAAAA==",
"_self": "dbs/0eUiAA==/colls/0eUiAJMAdQA=/docs/0eUiAJMAdQDl9QAAAAAAAA==/",
"_etag": "\"27014d93-0000-0000-0000-5b7ba4ae0000\"",
"_attachments": "attachments/"

The Document itself is updated properly by the Stored Procedure, and the changes (including the new _ts) can be verified immediately in Data Explorer.

I also tried executing a small query after the upsert/replace and even this doesn't work inside the same Stored Procedure:

SELECT c._ts FROM c WHERE c.id='f21d829d-2de5-0a27-8886-ff2c3ddb2119'

Return value from Stored Procedure:

[
    {}
]

Result in Data Explorer (run as SQL Query):

[
    {
        "_ts": 1534831246
    }
]

Stored Procedure code:

function UpdatePartial(id, update, rootNode){

    var context = getContext();
    var collection = context.getCollection();

    var query = `SELECT * FROM c WHERE c.id='${id}'`;

    var queryAccepted = collection.queryDocuments(collection.getSelfLink(), query, {}, onQueryResponse);
    if(!queryAccepted) throw "Unable to query DocumentDB";

    function onQueryResponse(err, documents, responseOptions) {

        if(err){
            throw err;
        }

        if(documents.length === 0){
            throw `Could not find document with id [${id}]`;
        }

        var source = documents[0];
        update = JSON.parse(update);

        if(rootNode){
            source[rootNode] = Merge(source[rootNode], update);
        } else {
            source = Merge(source, update);
        }

        var updateAccepted = collection.replaceDocument(source._self, source, onUpdateResponse);
        if(!updateAccepted) throw "Unable to update DocumentDB";

    }

    function onUpdateResponse(err, resource, options){

        if(err){
            throw err;
        }

        context.getResponse().setBody({"_ts": resource._ts || ''});

        // use this to return the entire document instead
        // context.getResponse().setBody(resource);

        // uncomment these lines to execute the query
        // var query = `SELECT c._ts FROM c WHERE c.id='${id}'`;
        // console.log(query);
        // collection.queryDocuments(collection.getSelfLink(), query, onTimeStampResponse);

    }

    function onTimeStampResponse(err, resource){

        if(err){
            throw err;
        }

        context.getResponse().setBody(resource);      

    }

    
    function Merge(source, update) {

        for (var key in update) {
        
            try {
        
                if ( update[key].constructor==Object ) {
                    source[key] = Merge(source[key], update[key]);
                } else {
                    source[key] = update[key];
                }
        
            } catch(err) {
                source[key] = update[key];
            }
        
        }

        return source;

    }


}

Here is the node.js code that calls the Stored Procedure:

exports.executeSproc = function(id, update, callback){

  let url = getCollectionUrl(config.database, config.collection) + '/sprocs/' + 'UpdatePartial';
  let options = [id, update];
  
  client.executeStoredProcedure(url, options, function(err, resource){

    if(err){
      console.error(`ERROR in documentdb.executeSproc\nid was:${id}\nUpdate was: ${JSON.stringify(update)}\nError:\n${JSON.stringify(err,null,2)}`);
      callback(err);
      return;
    }

    callback(resource);

  });

}
@roopeshwar
Copy link

+1 Facing the same issue

@muwaqar
Copy link

muwaqar commented Oct 10, 2018

We are facing the same issue as well.

@yulang-wang
Copy link

yulang-wang commented Mar 21, 2019

+1. This issue also appear in createDocument

image

@drago-draganov
Copy link

+1

3 similar comments
@davidhjones
Copy link

+1

@nganbread
Copy link

+1

@dolenox
Copy link

dolenox commented May 17, 2022

+1

@koltachev
Copy link

_ts is not assigned until end of transaction and that is after script code is finished, this means that while script (sproc) is running _ts is not yet available for documents change by current script transaction. For script transactions, same _ts (and same LSN) will be assigned to all docs updated as part of the transaction.

I guess that doesn't help much, as you would still need to obtain the _ts of a doc updated within script. Using JS ways like new Date object is one way though in some cases it may differ from actual one in updated docs. Anyhow, from within script it's not possible to retrieve transaction _ts. On client side that would be possible but I don't think there is a header for that. Nevertheless will look into adding one.

@drago-draganov
Copy link

It's great indeed to see a response 3 years later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants