Re: Re: FormBuilder and QuickForm_Controller
| From: | Justin Patrin | Date: | Wed, 09 Mar 2005 18:04:40 +0000 |
| Subject: | Re: Re: FormBuilder and QuickForm_Controller | ||
| References: | 1 2 3 4 | Groups: | php.pear.general |
| Request: | Send a blank email to pear-general+get-17935@lists.php.net to get a copy of this message | ||
On Wed, 9 Mar 2005 10:00:44 +0000, Edward Grace <ej.grace@imperial.ac.uk> wrote:
> Dear Justin,
>
> Thanks for getting back to me so rapidly. I have spent a morning
> "fiddling"...
>
> > Well, it does work for me. ;-)
>
> Doubtless ;-)
>
> > You should have opened a bug report if the newer versions broke your
> > scripts. Oh well, we'll try to fix it now.
>
> Apathy rules! Well, it would if it could be bothered!
>
> I'm new to PHP and Pear, I was initilaly scouting around for components to
> build a DB app, so was really looking for stuff that works out of the box.
> Of course now I quite like the idea behind DO and FormBuilder. While it's
> not necessarilly a good idea to commit oneself to something which is "Beta"
> it's fun.... !
Well, this does work fine out of the box for me. Then again, I'm using
mysql and have been using it since way back, so...
It's beta only because I keep futzing with it. And I also haven't
tested it on enough DB servers. I only test (right now) on mysql, so
it's quite likely there's a PostGres problem. It could also be a DO
problem.
>
> > The problem is probably with _getPrimaryKey(). Please look into this
> > function and see if you can find any reason it doesn't work with your
> > DOs. It *looks* like one of these calls is returning '', an empty
> > string (perhaps sequenceKey()?).
>
> Perhaps this is a DO issue? One thing I noticed was the sequences generated
> by the DO when using (say) ->insert() are not the same as using the raw SQL.
> This is worrying, i.e. while ->insert() always increments SERIAL keys and so
> does the SQL INSERT, they do so independently! This means one can clash with
> the other.
This does sound like a DO issue to me. Check your db.ini (where db is
the name of the db) file and find [table__keys] (where table is the
table name) and show us what's in there.
Also, since I don't know how SERIAL works...well, let me RTFM...
Ok, it looks to me like SERIAL is bacially the same as INT UNSIGNED
NOT_NULL AUTO_INCREMENT in mysql. I am also assuming that inserting a
record (without the SERIAL column) will create a new "nextval" for it
in the DB.
So, looks like your db.ini should have this in that [table__keys] section:
field = N
where field is the name of the field.
Now, I don't know for sure what DB and DB_DO do with SERIAL columns in
PostGres. If the entry is as above (or changing it to that doesn't fix
the problem) then try overriding the sequenceKey() function of your DO
like this:
function sequenceKey() {
return array('field', true, false);
}
This tells DO that the field 'field' is a native sequence and not to
use DB's sequence generation for it (you'll probably notice a
table__seq table in your DB which DB is using to create a sequence).
Hopefully this last will fix it if nothing else.
>
> I have just made a decision to only use ->insert() methods. However this is
> not ideal in the long term.
>
> Do you think this could be related to the _primary_key issue?
>
> > I'd appreciate it if you could make the appropriate DO and send back
> > the output of this:
>
> Done below.
>
> N.B. In case it matters, am using PostgreSQL 7.4.7 and PHP 4.3.10.
>
> SQL commands to build an example table.
>
> CREATE TABLE test (
> index SERIAL,
> name VARCHAR(512),
> note VARCHAR(1024),
You may want to add:
UNIQUE(index),
as later versions of PostGreSQL don't do this automatically (from the docs)
http://pgsqld.active-venture.com/datatype.html#DATATYPE-SERIAL
> PRIMARY KEY (index)
> );
>
> Resulting DO generated by createTables.php
>
> <?php
> /**
> * Table Definition for paperstatus
> */
> require_once 'DB/DataObject.php';
>
> class DataObjects_Test extends DB_DataObject
> {
> ###START_AUTOCODE
> /* the code below is auto generated do not remove the above tag */
>
> var $__table = 'test'; // table name
> var $index; // int4(4) not_null
> default_nextval%28public.test_index_seq%29 primary_key
> var $name; // varchar(-1)
> var $note; // varchar(-1)
>
> /* ZE2 compatibility trick*/
> function __clone() { return $this;}
>
> /* Static get */
> function staticGet($k,$v=NULL) { return
> DB_DataObject::staticGet('DataObjects_Test',$k,$v); }
>
> /* the code above is auto generated do not remove the tag below */
> ###END_AUTOCODE
> }
>
> Note, the DB_DATAOBJECT_NO_OVERLOAD which is required for PHP 4. x, mentioned
> here in case it's a problem.
Always set this in PHP4...(/me grumbles)
>
> // ******************** Test script *************************
> <?php
> define('DB_DATAOBJECT_NO_OVERLOAD',true);
> require_once('DB/DataObject.php');
> // If so then do all the configuration for the Data Objects and FormBuilder
> require_once('PEAR.php');
> $options = &PEAR::getStaticProperty('DB_DataObject','options');
> $config = parse_ini_file('/var/www/php/OJ/DataObjects/DataObjects.ini',TRUE);
> $options = $config['DB_DataObject'];
> require_once('DB/DataObject/FormBuilder.php');
> $do = DB_DataObject::factory('test');
> echo "<pre>";
> echo '
> PK
> ';
> var_dump($do->_primary_key);
> echo '
> SK
> ';
> var_dump($do->sequenceKey());
> echo '
> K
> ';
> var_dump($do->keys());
> echo "</pre>";
> ?>
>
> /********* RESULT *********************/
>
> PK
>
> Notice: Undefined property: _primary_key in /var/www/html/test.php on line
> 15
>
> NULL
>
> SK
> array(3) {
> [0]=>
> string(5) "index"
> [1]=>
> bool(false)
> [2]=>
> bool(false)
> }
Yep, this is likely your problem. Make the second one true (as above)
and you should be good.
>
> K
> array(1) {
> [0]=>
> string(5) "index"
> }
>
> > Then try changing the _getPrimaryKey function in FormBuilder.php to
> > this and see if it works:
> >
> > function _getPrimaryKey(&$do) {
> > if (isset($do->_primary_key) && strlen($do->_primary_key)) {
> > return $do->_primary_key;
> > } elseif (($seq = $do->sequenceKey()) && isset($seq[0]) &&
> > strlen($seq[0])) {
> > return $seq[0];
> > } else {
> > if (($keys = $do->keys()) && isset($keys[0]) &&
> > strlen($keys[0])) { return $keys[0];
> > }
> > }
> > $this->debug('Error: Primary Key not found for table
> > '.$do->tableName());
> > return false;
> > }
>
> Almost does.. Now when using it on tables which have links I get:
>
> Notice: Undefined index: database
> in /usr/share/pear/DB/DataObject/FormBuilder/QuickForm/PopupSelect.php on
> line 103
Hehe, oops. That's an old throwback line to when I implemented this
feature in DB_DO_FB_Frontend and since I usually (always) test within
the frontend, I missed this notice. It should be safe to remove this
line, it's commented JavaScript anyway. (I've done this and the above
in CVS, BTW).
>
> Other version info
>
> DB 1.7.2 stable
> DB_DataObject 1.7.7 stable
> DB_DataObject_FormBuilder 0.12.1 beta
> HTML_QuickForm 3.2.4pl1 stable
>
> So,
>
> I'm happy to try things, where too now?
>
Always glad to find users who are willing to debug along with me.
--
Justin Patrin