<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Aug 7, 2014 at 9:43 PM, Nicolas Chauvat <span dir="ltr"><<a href="mailto:nicolas.chauvat@logilab.fr" target="_blank">nicolas.chauvat@logilab.fr</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="">On Thu, Aug 07, 2014 at 10:14:47AM +0200, Yann Cointepas wrote:<br>
> I use multiple requests transactions because users are sending packages of<br>
> data. We garantie that a package that cannot be fully integrated in the<br>
> base will be rejected (and possibly corrected and resent by the<br>
> user).<br>
<br>
</div>What are the reasons that a package can be rejected for?<br></blockquote><div><br></div><div>It may be an error in the user data (e.g. invalid subject identifer) even if we try to detect these errors early. There are also errors in the code for pushing the data. It is changing because we are often adding new studies, new data types and new kind of processings in our data flow. <br>

<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class=""><br>
> Rejected package leave nothing in the base. Since a package can contains<br>
> various data (e.g. MRI Scans, MRI scans with processing results, only<br>
> processing results, etc.), the content of the package in processed in a<br>
> transaction.<br>
<br>
</div>You could devise an Upload or Transaction object and use<br>
<a href="https://www.cubicweb.org/project/cwclientlib" target="_blank">https://www.cubicweb.org/project/cwclientlib</a> to implement the<br>
following workflow:<br>
<br>
1) create a new Upload object<br>
<br>
2) add scans, results, etc to the Upload object<br>
<br>
3) check the correctness of the Upload<br>
<br>
   if it is correct -> move its content to the "standard context" of<br>
   the db, making it available to other users<br>
<br>
   if it is not correct -> delete the upload and all its content<br>
<br>
IIRC, we do something similar when uploading files in<br>
<a href="https://www.simulagora.com/" target="_blank">https://www.simulagora.com/</a> and we can for example resume interrupted<br>
file transfers to reach correctness before the upload becomes valid.<br></blockquote><div><br></div><div>I did not know this cwclientlib I will definitely have a look. However, if there is a commit after each RQL request, I see two difficulties to implement the workflow you proposed:<br>

<br></div>1) For efficiency, I rely partialy on the Cubicweb constraints to detect some errors in the data (especially unique constraints if someone send twice the same data). For instance, if in a transaction I am asked to add two subjects but the second is already in the database. Either, I will need to reimplement the constraint (looking for existing subjects both in the database and in the Upload object :() or I will have to find a way, when the second subject raises an RQL constraint error, to remove all that have been successfully inserted so far. IMHO my only option is to make a single request with all the modifications in the transaction. But this lead to the second difficulty.<br>

<div><br>2) I need to connect some objects that have been inserted during the session. I use the eid returned by INSERT for that. I do not how to do that in a single RQL command.<br><br></div><div>Let's take an example. There is a database with only a subject S. I receive the following data:<br>

<br></div><div>Subject N<br></div><div>MRI scan for N<br></div><div>Subject S (error it is already in the database)<br></div><div>MRI scan for S<br><br></div><div>Let's suppose it is inserted by the following code:<br>

<br></div><div>db = CubicwebAPIWithRollback()<br></div><div>try:<br></div><div>    s = db.rql('INSERT Subject X: X identifier "N")[0][0]<br></div><div>    db. rql('INSERT Scan X: X concerns S, S eid %d' % s)<br>

<div>    s = db.rql('INSERT Subject X: X identifier "S")[0][0]<br></div>    db. rql('INSERT Scan X: X concerns S, S eid %d' % s)<br>except:<br></div><div>    db.rollback()<br></div><div>else:<br></div>

<div>    db.commit()<br></div><div><br></div><div>Because of the constraint error, there will be no change in the database at the end of this code. How could I construct a code that would do the same without transactions ?<br>

</div><div><br></div><div>Sorry for this long message.<br><br></div><div>      Yann<br></div><br></div></div></div>