Re: [PHP-PEAR] possible bug in DB/pgsql.php

[email protected]
Newsgroups php.pear
Message-ID <3A90F90B.2551.A5F5B5D@localhost>
On 18 Feb 2001, at 16:11, Stig S. Bakken wrote:

> > So, at the moment, DB_pgsql does only half of the work. To do it
> > full, there should be an explicit "begin" somewhere. If this cannot
> > be "user required" as i suggested in my previous message, the
> > hard part is finding where...
> > 
> Ok, what if we take away the implicit "commit" after each query when
> auto-commit is on, and add an implicit "begin" before each query when
> auto-commit is off instead?  I would like to avoid having more than one
> transaction paradigm. :-)
> 
Yep, this I understand...  doing that way things could work, though 
in a little hackish way.
i.e. in this way if I'd do (syntax is really pseudo, I've not the 
sources at hand):

$db->auto_commit(off);
/* start transaction */
$db->query(some_query); <- this does a "begin"
...some logic...
$db->query(some_other_query); <- this does another "begin", 		
                                                          warning message
/* close transaction */
$db->commit();

For the moment, this would work, since multiple begins raise only 
"NOTICEs" and don't break anything (and you've already showed 
you know how to silence them :-)), but I wouln't choose this 
solution so steadfastly. It's more than possible that future versions 
of pgsql raise errors instead of warnings, or even open a nested 
transaction (OK, this is not in the TODO list for at least next year, 
so we can relax for the moment...), and I'm not even sure that all 
_existing_ versions of pgsql digest the "multiple" begin without 
getting irritated.
Maybe the problem can be solved using some sort of hidden "flag" 
that tells us if we are in "transaction mode" or not, and using this 
flag to send a "begin" or not.

i.e. the code for the query method could be something like:

function query($string)
{
	...
	if (($this->autocommit==0) && (!$this->trans_block))
	{
		pg_exec($this->conn_id,"BEGIN WORK");
		$this->trans_block=TRUE;
	}
	... do query ...
}

function commit()
{
	if ($this->trans_block)
	{
		pg_exec($this->conn_id,"COMMIT WORK");
		$this->trans_block=FALSE;
	}
	else
	{
		error("Nothing to commit!");
	}
}

rollback() would be symmetrical, and $trans_block should be init to 
FALSE in the costructor. (again, never mind the sintax, I'm just 
pseudocoding... hope to be readable %-)).

owever, I'm using hypotethical tense here because AFAIU PEAR 
db object can be used with multiple connections (that is, for each 
page we should have just one $db object but we could have many 
$conn_id, right?), and I'm afraid this way things won't work. Unless, 
instead of using a simple boolean flag, we use this $trans_block 
thingy to store the connection id of each backend that has a 
"pending" connection (but then it could not be a scalar any more).
So the test to do in the pre-query part should be:
	
-"Do I have the present connection in the list of pending transaction 
blocks?"
{
	YES: { "Skip the BEGIN statement" }
	NO: { "Issue the BEGIN statement on the present connection"
	   "Add the present connection to the list of pending ones"}

And, simmetrically, a commit or rollback should remove the 
connection from the list of pending transactions.

Hmm, maybe I'm straying too far...I'm not too content of my own 
suggestions. Your turn...

Ciao!


/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Fabrizio Ermini               Alternate E-mail:
C.so Umberto, 7               [email protected]
loc. Meleto Valdarno          Mail on GSM: (keep it short!)
52020 Cavriglia (AR)          [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.