<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/4.2.3">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#ffffff">
Hi,<BR>
<BR>
I have changed the non-pooling stuff to be C function based instead of DB URL based.&nbsp; I have only implemented and tested this for PostgreSQL as that is the only DB module I use - but it should be trivial to add to other DB modules in the future if anyone needs that.<BR>
<BR>
If I have time next week I will change BEGIN/COMMIT/ROLLBACK to be API based (I will only implement and test the APIs for PostgreSQL) and also disable retries automatically (again just within PostgreSQL) when they are used.&nbsp; If I do this I will make sure I change the RLS code that calls the APIs to check the functions are non-null before using them - so they will continue to work with other DBs (but of course better with PostgreSQL).&nbsp; Once the function pointers exist and the PostgreSQL APIs have been implemented it should be straight-forward enough for others to port to MySQL/Oracle/SQLite and so on.<BR>
<BR>
Regards,<BR>
<BR>
Peter<BR>
<BR>
On Fri, 2012-04-20 at 16:52 +0100, Peter Dunkley wrote:<BR>
<BLOCKQUOTE TYPE=CITE>
    Hi,<BR>
    <BR>
    I am just adding a new db init function (init_nopool) to the generic _dbf data-structure now.&nbsp; I will implement the actual init_nopool function just for PostgreSQL.&nbsp; We only need this for a small proprietary module we have, so I don't expect anyone else to use this right away.<BR>
    <BR>
    If I have time I will make the BEGIN/COMMIT/ROLLBACK functions API functions next week, but I want to get the presence notifier stuff done first.<BR>
    <BR>
    Thanks,<BR>
    <BR>
    Peter<BR>
    <BR>
    On Fri, 2012-04-20 at 17:44 +0200, Daniel-Constantin Mierla wrote:<BR>
    <BLOCKQUOTE TYPE=CITE>
        Hello,<BR>
        <BR>
        On 4/20/12 5:18 PM, Peter Dunkley wrote: <BR>
        <BLOCKQUOTE TYPE=CITE>
            Hi Daniel,<BR>
            <BR>
            How would we do the non-pooling stuff inside the module?<BR>
        </BLOCKQUOTE>
        <BR>
        it can be via new API field, like 'newinit' -- it is anyhow needed only in one or few places, so the other modules using the DB API will not change, just the db conenctors.<BR>
        <BR>
        My concern is actually about the fact that the user will have to know that a module requires internally new connections for same db url. From my point of view, the user knows that the module has to interact with the database and set a DB URL parameter for that.<BR>
        <BR>
        Jan Janak had also a point about the URL format, the '*' not being really right and safe used as part of schema.<BR>
        <BR>
        Therefore two things here:<BR>
        - do we need to specify from config whether it has to be a new connection or not? If it is mandatory to work properly, then it is not a configuration option<BR>
        - how do distinguish from asking a pooled and non-pooled connection. If we need non-pooled is needed to be specified via a config option, then we should do it according tot he URL format, otherwise, should be something internal, with no change in the existing DB url syntax.<BR>
        <BR>
        <BLOCKQUOTE TYPE=CITE>
            <BR>
            I believe BEGIN/COMMIT/ROLLBACK are standard SQL.&nbsp; I did a quick search online before making the change and found that they seem to be documented for PostgreSQL, MySQL SQLlite, and SQL Server.&nbsp; The wrapper functions first check to see if DB_CAP_RAW_QUERY is set for the database connection it the functions just return without error if raw queries are not available.&nbsp; I would have thought it safe to assume that if raw queries are supported the DB module supports SQL?<BR>
        </BLOCKQUOTE>
        <BR>
        It might be true right now, but even supporting raw_query, it may not have support for transactions. Raw query support can be implemented also for non-SQL. Relying on another generic API member to assume globally an existing specific feature, looks a bit odd for me.<BR>
        <BR>
        I don't know, right now it just feels that such extensions are more appropriate as API members and implemented inside connectors. It has also the benefit of being able to control better the behavior, if what Klaus pointed is needed, like disabling auto-reconnect.<BR>
        <BR>
        The feature is there, reworking a bit during the testing does not mean new features, so it is not a presure to change everything right now. But we should do the right decision so we don 't need to change in short term.<BR>
        <BR>
        Cheers,<BR>
        Daniel<BR>
        <BR>
        <BR>
        <BR>
        <BLOCKQUOTE TYPE=CITE>
            <BR>
            Peter<BR>
            <BR>
            On Fri, 2012-04-20 at 17:09 +0200, Daniel-Constantin Mierla wrote:<BR>
            <BLOCKQUOTE TYPE=CITE>
                Hello,<BR>
                <BR>
                since it came back in the spotlight, I think the non-pooling flag should not be exposed to the config. The admin has usually no knowledge of modules' internals to know it has to configure with a new connection -- it should be only inside the module.<BR>
                <BR>
                Then, is BEGIN/COMMIT/ROLLBACK a standard everywhere across DB/SQL servers? Even if in SQL, the DB api is not only for them. I seems to be that these new functions should be better part of DB api and implemented inside the db modules. That allows also for temporarily disabling of reconnect when needed, Eventually, other DB (non-SQL) connectors can have custom implementation.<BR>
                <BR>
                Cheers,<BR>
                Daniel<BR>
                <BR>
                On 4/20/12 4:56 PM, Peter Dunkley wrote: <BR>
                <BLOCKQUOTE TYPE=CITE>
                    I'll update the RLS documentation to make that clear.<BR>
                    <BR>
                    As for the second item... The non-pooling stuff is still done with a '*' at the start of the DB URL.&nbsp; The DB stuff doesn't use the standard Kamailio URI parser so making DB pooling a proper parameter is not as simple as I'd hoped it'd be.&nbsp; Also, the parameter stuff would be in lib/srdb1 whereas the retries parameter is in the DB modules themselves (modules/db_mysql and modules/db_postgres), so I am not sure disabling automatic reconnect on a per connection basis will be that simple to add.<BR>
                    <BR>
                    I think I'll leave those DB changes to someone a bit more familiar with the modules <IMG SRC="cid:part1.02030408.06090506@gmail.com" ALIGN="middle" ALT=":-)" BORDER="0"><BR>
                    <BR>
                    Thanks,<BR>
                    <BR>
                    Peter<BR>
                    <BR>
                    On Fri, 2012-04-20 at 16:24 +0200, Klaus Darilion wrote: 
                    <BLOCKQUOTE TYPE=CITE>
<PRE>
Now you should mention that auto reconnect must be disabled otherwise 
reconnect during transactions will cause inconsistencies.

Probably it would be cool if automatically reconnect would be configured 
with the db_url (just as the non-pooling parameter)

regards
Klaus

On 20.04.2012 15:02, Peter Dunkley wrote:
&gt; Module: sip-router
&gt; Branch: master
&gt; Commit: f71bdc3cbdf5acdf243217778e4159f2e6ab341d
&gt; URL:    <A HREF="http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f71bdc3cbdf5acdf243217778e4159f2e6ab341d">http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f71bdc3cbdf5acdf243217778e4159f2e6ab341d</A>
&gt;
&gt; Author: Peter Dunkley&lt;<A HREF="mailto:peter.dunkley@crocodile-rcs.com">peter.dunkley@crocodile-rcs.com</A>&gt;
&gt; Committer: Peter Dunkley&lt;<A HREF="mailto:peter.dunkley@crocodile-rcs.com">peter.dunkley@crocodile-rcs.com</A>&gt;
&gt; Date:   Fri Apr 20 14:00:22 2012 +0100
&gt;
&gt; modules_k/rls: Used db_begin() and db_commit() around blocks of related DB queries and updates
&gt;
&gt; - This makes these related sets of DB queries a single transaction.  As Klaus
&gt;    pointed out this if you don't do this you can get inconsistencies when using
&gt;    multiple presence servers.
&gt;
&gt; ---
&gt;
&gt;   modules_k/rls/notify.c          |   12 ++++++++++++
&gt;   modules_k/rls/resource_notify.c |   24 ++++++++++++++++++++++++
&gt;   modules_k/rls/rls_db.c          |   21 +++++++++++++++++++++
&gt;   3 files changed, 57 insertions(+), 0 deletions(-)
&gt;
&gt; diff --git a/modules_k/rls/notify.c b/modules_k/rls/notify.c
&gt; index 082fbfa..1836808 100644
&gt; --- a/modules_k/rls/notify.c
&gt; +++ b/modules_k/rls/notify.c
&gt; @@ -128,6 +128,12 @@ int send_full_notify(subs_t* subs, xmlNodePtr rl_node, str* rl_uri,
&gt;                   goto error;
&gt;           }
&gt;
&gt; +        if (db_begin(&amp;rlpres_dbf, rlpres_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in BEGIN\n&quot;);
&gt; +                goto error;
&gt; +        }
&gt; +
&gt;           if(rlpres_dbf.query(rlpres_db, query_cols, 0, query_vals, result_cols,
&gt;                                           1, n_result_cols,&amp;str_resource_uri_col,&amp;result )&lt;  0)
&gt;           {
&gt; @@ -257,6 +263,12 @@ int send_full_notify(subs_t* subs, xmlNodePtr rl_node, str* rl_uri,
&gt;                   goto error;
&gt;           }
&gt;
&gt; +        if (db_commit(&amp;rlpres_dbf, rlpres_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in COMMIT\n&quot;);
&gt; +                goto error;
&gt; +        }
&gt; +
&gt;           xmlFree(rlmi_cont-&gt;s);
&gt;           pkg_free(rlmi_cont);
&gt;
&gt; diff --git a/modules_k/rls/resource_notify.c b/modules_k/rls/resource_notify.c
&gt; index 29e0b11..87ce806 100644
&gt; --- a/modules_k/rls/resource_notify.c
&gt; +++ b/modules_k/rls/resource_notify.c
&gt; @@ -893,6 +893,12 @@ static void timer_send_full_state_notifies(int round)
&gt;                   goto done;
&gt;           }
&gt;
&gt; +        if (db_begin(&amp;rls_dbf, rls_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in BEGIN\n&quot;);
&gt; +                goto done;
&gt; +        }
&gt; +
&gt;           /* Step 1: Find rls_watchers that require full-state notification */
&gt;           if (rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
&gt;                                   1, n_result_cols, 0,&amp;result)&lt;  0)
&gt; @@ -912,6 +918,12 @@ static void timer_send_full_state_notifies(int round)
&gt;                   goto done;
&gt;           }
&gt;
&gt; +        if (db_commit(&amp;rls_dbf, rls_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in COMMIT\n&quot;);
&gt; +                goto done;
&gt; +        }
&gt; +
&gt;           /* Step 3: Full-state notify each watcher we found */
&gt;           rows = RES_ROWS(result);
&gt;           for (i = 0; i&lt;  RES_ROW_N(result); i++)
&gt; @@ -1025,6 +1037,12 @@ static void timer_send_update_notifies(int round)
&gt;                   goto done;
&gt;           }
&gt;
&gt; +        if (db_begin(&amp;rlpres_dbf, rlpres_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in BEGIN\n&quot;);
&gt; +                goto error;
&gt; +        }
&gt; +
&gt;           if(rlpres_dbf.query(rlpres_db, query_cols, 0, query_vals, result_cols,
&gt;                                           1, n_result_cols,&amp;str_rlsubs_did_col,&amp;result)&lt;  0)
&gt;           {
&gt; @@ -1042,6 +1060,12 @@ static void timer_send_update_notifies(int round)
&gt;                   goto error;
&gt;           }
&gt;
&gt; +        if (db_commit(&amp;rlpres_dbf, rlpres_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in COMMIT\n&quot;);
&gt; +                goto error;
&gt; +        }
&gt; +
&gt;           send_notifies(result, did_col, resource_uri_col, auth_state_col, reason_col,
&gt;                     pres_state_col, content_type_col);
&gt;   error:
&gt; diff --git a/modules_k/rls/rls_db.c b/modules_k/rls/rls_db.c
&gt; index 6a00c21..46bda91 100644
&gt; --- a/modules_k/rls/rls_db.c
&gt; +++ b/modules_k/rls/rls_db.c
&gt; @@ -124,6 +124,7 @@ int delete_expired_subs_rlsdb( void )
&gt;           int i;
&gt;           subs_t subs;
&gt;           str rlsubs_did = {0, 0};
&gt; +        int transaction_started = 0;
&gt;
&gt;           if(rls_db == NULL)
&gt;           {
&gt; @@ -148,6 +149,13 @@ int delete_expired_subs_rlsdb( void )
&gt;           result_cols[r_to_tag_col=n_result_cols++] =&amp;str_to_tag_col;
&gt;           result_cols[r_from_tag_col=n_result_cols++] =&amp;str_from_tag_col;
&gt;
&gt; +        if (db_begin(&amp;rls_dbf, rls_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in BEGIN\n&quot;);
&gt; +                goto error;
&gt; +        }
&gt; +        transaction_started = 1;
&gt; +
&gt;           if(rls_dbf.query(rls_db, query_cols, query_ops, query_vals, result_cols,
&gt;                                   n_query_cols, n_result_cols, 0,&amp;result )&lt;  0)
&gt;           {
&gt; @@ -213,12 +221,25 @@ int delete_expired_subs_rlsdb( void )
&gt;                   pkg_free(rlsubs_did.s);
&gt;           }
&gt;
&gt; +        if (db_commit(&amp;rls_dbf, rls_db)&lt;  0)
&gt; +        {
&gt; +                LM_ERR(&quot;in COMMIT\n&quot;);
&gt; +                goto error;
&gt; +        }
&gt; +
&gt;           if(result) rls_dbf.free_result(rls_db, result);
&gt;           return 1;
&gt;
&gt;   error:
&gt;           if (result) rls_dbf.free_result(rls_db, result);
&gt;           if (rlsubs_did.s) pkg_free(rlsubs_did.s);
&gt; +
&gt; +        if (transaction_started)
&gt; +        {
&gt; +                if (db_commit(&amp;rls_dbf, rls_db)&lt;  0)
&gt; +                        LM_ERR(&quot;in COMMIT\n&quot;);
&gt; +        }
&gt; +
&gt;           return -1;
&gt;   }
&gt;
&gt;
&gt;
&gt; _______________________________________________
&gt; sr-dev mailing list
&gt; <A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>
&gt; <A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
</PRE>
                    </BLOCKQUOTE>
                    <BR>
                    <TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
                    <BR>
                    <BR>
<PRE>
_______________________________________________
sr-dev mailing list
<A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>
<A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
</PRE>
                </BLOCKQUOTE>
                <BR>
<PRE>
-- 
Daniel-Constantin Mierla
Kamailio Advanced Training, April 23-26, 2012, Berlin, Germany
<A HREF="http://www.asipto.com/index.php/kamailio-advanced-training/">http://www.asipto.com/index.php/kamailio-advanced-training/</A>
</PRE>
            </BLOCKQUOTE>
            <BR>
            <TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
        </BLOCKQUOTE>
        <BR>
<PRE>
-- 
Daniel-Constantin Mierla
Kamailio Advanced Training, April 23-26, 2012, Berlin, Germany
<A HREF="http://www.asipto.com/index.php/kamailio-advanced-training/">http://www.asipto.com/index.php/kamailio-advanced-training/</A>
</PRE>
    </BLOCKQUOTE>
    <BR>
    <TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
_______________________________________________
sr-dev mailing list
<A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>
<A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>

</PRE>
</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>