PHP Unframework
PHP Unframework
I must be pretty dense. I'm trying to insert a record into a table. I've setup the db connection and performed fORM::attach. I can query the table just fine. When I try to create a new record and set the column values, and try to store, it causes a validation error. Apparently, flourish insists that I provide a value for the "id" column which is an auto_increment field. How do I provide it a value, if I don't know what it will be?
I've tried : $gtt_prob->setId(); $gtt_prob->setId(NULL);
etc.
How should this be done?
Don't provide any value and it will be automatically added.
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL
)engine=InnoDB;
$db = new fDatabase('mysql', 'my_db', 'login', 'password');
fORMDatabase::attach($db);
class User extends fActiveRecord {}
$user = new User();
$user->setFirstName('Will');
$user->setLastName('Bond');
$user->store();
Will, thanks for the quick response. However, that will not work for me. Unfortunately, the table is defined as follows:
CREATE TABLE `tcell_itue_issues` (
`id` int(10) unsigned NOT NULL auto_increment,
`start_gta` varchar(20) NOT NULL default '',
`end_gta` varchar(20) NOT NULL default '',
`pc` varchar(11) NOT NULL default '',
`stp_start` varchar(20) NOT NULL default '',
`stp_end` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `start_gta` (`start_gta`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
The NOT NULL on the primary key is causing the validation to trigger. Because this is legacy stuff, I can't change it.
I dropped your schema in and the following code worked without a hitch:
class TcellItueIssue extends fActiveRecord {}
$issue = new TcellItueIssue();
$issue->setStartGta('Test');
$issue->store();
Argh. Sorry to be wasting your time, but it's just not working for me:
$gsmnetdb = new fDatabase('mysql', DB, DB_USER, DB_PASS, DB_HOST, DB_PORT);
fORMDatabase::attach($gsmnetdb);
$gtt_prob = new Tcell_itue_issue();
$gtt_prob->setStart_gta('Testing8');
$gtt_prob->setEnd_gta('Testing9');
$gtt_prob->setPc('Testing10');
$gtt_prob->setStp_start('Testing11');
$gtt_prob->setStp_end('Testing21');
$gtt_prob->store();
Here is part of the error I get back:
)</pre><pre class="exposed">Uncaught Exception
------------------
{doc_root}/telcel_clean.php(20): fActiveRecord->store()
/home/ss7admin/jn_testing/gops_telcel/flourish/fActiveRecord.php(1787): fActiveRecord->validate()
<p>The following problems were found:</p>
<ul>
<li>ID: Please enter a value</li>
</ul></pre>
Will,
I also copied your code over exactly:
#!/usr/local/php-5.2.5/bin/php
<?php
/**
* Get the base constants
*/
require_once( realpath(dirname(__FILE__) . '/../includes/constants.php') );
class TcellItueIssue extends fActiveRecord {}
$issue = new TcellItueIssue();
$issue->setStartGta('Test');
$issue->store();
?>
Yet, I still get this error:
{doc_root}/new_file.php(14): fActiveRecord->store()
/home/ss7admin/jn_testing/gops_telcel/flourish/fActiveRecord.php(1787): fActiveRecord->validate()
<p>The following problems were found:</p>
<ul>
<li>ID: Please enter a value</li>
</ul></pre>n
What version of MySQL are you running?
Also, can you post the output of the following?
fCore::expose(fORMSchema::retrieve()->getColumnInfo('tcell_itue_issues'));
fCore::expose(fORMSchema::retrieve()->getKeys('tcell_itue_issues'));
I'm getting this:
Array
(
[id] => Array
(
[type] => integer
[not_null] => {true}
[auto_increment] => {true}
[default] => {null}
[valid_values] => {null}
[max_length] => {null}
[decimal_places] => {null}
)
[start_gta] => Array
(
[type] => varchar
[max_length] => 20
[not_null] => {true}
[default] => {empty_string}
[valid_values] => {null}
[decimal_places] => {null}
[auto_increment] => {false}
)
[end_gta] => Array
(
[type] => varchar
[max_length] => 20
[not_null] => {true}
[default] => {empty_string}
[valid_values] => {null}
[decimal_places] => {null}
[auto_increment] => {false}
)
[pc] => Array
(
[type] => varchar
[max_length] => 11
[not_null] => {true}
[default] => {empty_string}
[valid_values] => {null}
[decimal_places] => {null}
[auto_increment] => {false}
)
[stp_start] => Array
(
[type] => varchar
[max_length] => 20
[not_null] => {true}
[default] => {empty_string}
[valid_values] => {null}
[decimal_places] => {null}
[auto_increment] => {false}
)
[stp_end] => Array
(
[type] => varchar
[max_length] => 20
[not_null] => {true}
[default] => {empty_string}
[valid_values] => {null}
[decimal_places] => {null}
[auto_increment] => {false}
)
)
Array
(
[primary] => Array
(
[0] => id
)
[foreign] => Array
(
)
[unique] => Array
(
[0] => Array
(
[0] => start_gta
)
)
)
Hopefully we should be able to get to the bottom of this.
Will,
Thanks for all the help.
Unfortunately, I'm using MySQL 4.1.8 in this particular instance.
I think I see the problem here. Even though my table is defined as :
CREATE TABLE `tcell_itue_issues` (
`id` int(10) unsigned NOT NULL auto_increment,
`start_gta` varchar(20) NOT NULL default '',
`end_gta` varchar(20) NOT NULL default '',
`pc` varchar(11) NOT NULL default '',
`stp_start` varchar(20) NOT NULL default '',
`stp_end` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `start_gta` (`start_gta`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
The schema dump shows that auto_increment on the "id" field is set to false, whereas yours is set to true. How is that possible? I can confirm that the auto_increment does work when inserting records.
Array
(
[id] = Array
(
[type] = integer
[not_null] = {true}
[default] = {null}
[valid_values] = {null}
[max_length] = {null}
[decimal_places] = {null}
[auto_increment] = {false}
)
[start_gta] = Array
(
[type] = varchar
[max_length] = 20
[not_null] = {true}
[default] = {empty_string}
[valid_values] = {null}
[decimal_places] = {null}
[auto_increment] = {false}
)
[end_gta] = Array
(
[type] = varchar
[max_length] = 20
[not_null] = {true}
[default] = {empty_string}
[valid_values] = {null}
[decimal_places] = {null}
[auto_increment] = {false}
)
[pc] = Array
(
[type] = varchar
[max_length] = 11
[not_null] = {true}
[default] = {empty_string}
[valid_values] = {null}
[decimal_places] = {null}
[auto_increment] = {false}
)
[stp_start] = Array
(
[type] = varchar
[max_length] = 20
[not_null] = {true}
[default] = {empty_string}
[valid_values] = {null}
[decimal_places] = {null}
[auto_increment] = {false}
)
[stp_end] = Array
(
[type] = varchar
[max_length] = 20
[not_null] = {true}
[default] = {empty_string}
[valid_values] = {null}
[decimal_places] = {null}
[auto_increment] = {false}
)
)
Array
(
[primary] = Array
(
[0] = id
)
[foreign] = Array
(
)
[unique] = Array
(
[0] = Array
(
[0] = start_gta
)
)
)
What version of fSchema do you have?
Also, is the CREATE TABLE statement you provided above the output of SHOW CREATE TABLE?
fSchema Info:
/**
* Gets schema information for the selected database
*
* @copyright Copyright (c) 2007-2009 Will Bond
* @author Will Bond [wb] <will@flourishlib.com>
* @license http://flourishlib.com/license
*
* @package Flourish
* @link http://flourishlib.com/fSchema
*
* @version 1.0.0b13
* @changes 1.0.0b13 Fixed a bug with detecting PostgreSQL columns having both a CHECK constraint and a UNIQUE constraint [wb, 2009-02-27]
* @changes 1.0.0b12 Fixed detection of multi-column primary keys in MySQL [wb, 2009-02-27]
* @changes 1.0.0b11 Fixed an issue parsing MySQL tables with comments [wb, 2009-02-25]
* @changes 1.0.0b10 Added the ::getDatabases() method [wb, 2009-02-24]
* @changes 1.0.0b9 Now detects unsigned and zerofill MySQL data types that do not have a parenthetical part [wb, 2009-02-16]
* @changes 1.0.0b8 Mapped the MySQL data type `'set'` to `'varchar'`, however valid values are not implemented yet [wb, 2009-02-01]
* @changes 1.0.0b7 Fixed a bug with detecting MySQL timestamp columns [wb, 2009-01-28]
* @changes 1.0.0b6 Fixed a bug with detecting MySQL columns that accept `NULL` [wb, 2009-01-19]
* @changes 1.0.0b5 ::setColumnInfo(): fixed a bug with not grabbing the real database schema first, made general improvements [wb, 2009-01-19]
* @changes 1.0.0b4 Added support for MySQL binary data types, numeric data type options unsigned and zerofill, and per-column character set definitions [wb, 2009-01-17]
* @changes 1.0.0b3 Fixed detection of the data type of MySQL timestamp columns, added support for dynamic default date/time values [wb, 2009-01-11]
* @changes 1.0.0b2 Fixed a bug with detecting multi-column unique keys in MySQL [wb, 2009-01-03]
* @changes 1.0.0b The initial implementation [wb, 2007-09-25]
*/
The table definition I sent you is from a SHOW CREATE TABLE:
Table Create Table
----------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tcell_itue_issues CREATE TABLE `tcell_itue_issues` (
`id` int(10) unsigned NOT NULL auto_increment,
`start_gta` varchar(20) NOT NULL default '',
`end_gta` varchar(20) NOT NULL default '',
`pc` varchar(11) NOT NULL default '',
`stp_start` varchar(20) NOT NULL default '',
`stp_end` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `start_gta` (`start_gta`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Ok, this should hopefully get all the info I need. Can you paste the follow code on line 575 of fSchema and send me the output?
fCore::expose($create_sql);
fCore::expose($matches);
Will,
Here is the output of the script after adding your expose methods. There is some additional junk messaging in there from some testing I was doing.
$ ./telcel_clean.php
Notice: Undefined index: dirname in /home/ss7admin/jn_testing/gops_telcel/flourish/fCore.php on line 269
Notice: Undefined index: dirname in /home/ss7admin/jn_testing/gops_telcel/flourish/fCore.php on line 269
fResult Object
(
[affected_rows:private] => 0
[auto_incremented_value:private] =>
[character_set:private] =>
[current_row:private] =>
[extension:private] => array
[pointer:private] =>
[result:private] => Array
(
[0] => Array
(
[id] => 1
[start_gta] => Testing
[end_gta] =>
[pc] =>
[stp_start] =>
[stp_end] =>
)
)
[returned_rows:private] => 1
[sql:private] => SELECT * FROM adhoc.tcell_itue_issues LIMIT 5
[type:private] => mysql
[untranslated_sql:private] =>
)
String = TcellItueIssue
TABLE CLASS NAME Class name = Array
(
[TcellItueIssue] => tcell_itue_issues
)
<pre class="exposed">CREATE TABLE "tcell_itue_issues" (
"id" int(10) unsigned NOT NULL,
"start_gta" varchar(20) NOT NULL default '',
"end_gta" varchar(20) NOT NULL default '',
"pc" varchar(11) NOT NULL default '',
"stp_start" varchar(20) NOT NULL default '',
"stp_end" varchar(20) NOT NULL default '',
PRIMARY KEY ("id"),
UNIQUE KEY "start_gta" ("start_gta")
)</pre><pre class="exposed">Array
(
[0] => Array
(
[0] =>
"id" 10 unsigned NOT NULL,
[1] => id
[2] => int
[3] => 10
[4] => NOT NULL
)
[1] => Array
(
[0] =>
"start_gta" varchar(20) NOT NULL default '',
[1] => start_gta
[2] => varchar
[3] => 20
[4] => NOT NULL
[5] => ''
)
[2] => Array
(
[0] =>
"end_gta" varchar(20) NOT NULL default '',
[1] => end_gta
[2] => varchar
[3] => 20
[4] => NOT NULL
[5] => ''
)
[3] => Array
(
[0] =>
"pc" varchar(11) NOT NULL default '',
[1] => pc
[2] => varchar
[3] => 11
[4] => NOT NULL
[5] => ''
)
[4] => Array
(
[0] =>
"stp_start" varchar(20) NOT NULL default '',
[1] => stp_start
[2] => varchar
[3] => 20
[4] => NOT NULL
[5] => ''
)
[5] => Array
(
[0] =>
"stp_end" varchar(20) NOT NULL default '',
[1] => stp_end
[2] => varchar
[3] => 20
[4] => NOT NULL
[5] => ''
)
)</pre>
Fatal error: Uncaught exception 'fValidationException' with message '<p>The following problems were found:</p>
<ul>
<li>ID: Please enter a value</li>
</ul>' in /home/ss7admin/jn_testing/gops_telcel/flourish/fActiveRecord.php:1958
Stack trace:
#0 /home/ss7admin/jn_testing/gops_telcel/flourish/fActiveRecord.php(1787): fActiveRecord->validate()
#1 /home/ss7admin/jn_testing/gops_telcel/scripts/telcel_clean.php(20): fActiveRecord->store()
#2 {main}
thrown in /home/ss7admin/jn_testing/gops_telcel/flourish/fActiveRecord.php on line 1958
$
The interesting thing is the output of fCore::expose($create_sql). It shows that the id column does NOT have auto_increment.
Here is the exact output of the "show create table" command from the same database the script is accessing.
mysql> show databases;
+-------------+
| Database |
+-------------+
| adhoc |
| gsmnet_dev |
| gsmnet_test |
| mysql |
+-------------+
4 rows in set (0.00 sec)
mysql> use adhoc
Database changed
mysql> show tables;
+-------------------+
| Tables_in_adhoc |
+-------------------+
| tcell_itue_issues |
+-------------------+
1 row in set (0.00 sec)
mysql> show create table tcell_itue_issues;
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tcell_itue_issues | CREATE TABLE `tcell_itue_issues` (
`id` int(10) unsigned NOT NULL auto_increment,
`start_gta` varchar(20) NOT NULL default '',
`end_gta` varchar(20) NOT NULL default '',
`pc` varchar(11) NOT NULL default '',
`stp_start` varchar(20) NOT NULL default '',
`stp_end` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `start_gta` (`start_gta`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
I don't understand how the client could be returning invalid information. To clarify, I wanted to note that on this machine, I have both a MySQL 4 client and a MySQL 5 client. The PHP script is using the MySQL 5 client to access the 4.1.8 database. However, I've done this exact processing logging into MySQL via command line using both the 4 and 5 clients. They both provide information identical to the second file.
From a little bit of searching, it seems as though some how the NO_FIELD_OPTIONS flag is being enabled when running Flourish, which causes the AUTO_INCREMENT option to be hidden. http://dev.mysql.com/doc/refman/4.1/en/server-sql-mode.html.
Can you execute the following SQL from your command line client and then from fDatabase?
SELECT VERSION(), USER(), DATABASE();
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;
Will,
Here's the results of these queries.
mysql> SELECT VERSION(), USER(), DATABASE();
+-----------+---------------+------------+
| VERSION() | USER() | DATABASE() |
+-----------+---------------+------------+
| 4.1.8a | replaced@replaced | adhoc |
+-----------+---------------+------------+
1 row in set (0.00 sec)
mysql> SELECT @@GLOBAL.sql_mode;
+-------------------+
| @@global.sql_mode |
+-------------------+
| |
+-------------------+
1 row in set (0.00 sec)
mysql> SELECT @@SESSION.sql_mode;
+--------------------+
| @@session.sql_mode |
+--------------------+
| |
+--------------------+
1 row in set (0.00 sec)
mysql>
Those look like they are just from your mysql command line client. Can you execute this PHP too?
#php
$results = $db->query('SELECT VERSION(), DATABASE(); SELECT @@GLOBAL.sql_mode; SELECT @@SESSION.sql_mode;');
foreach ($results as $result) {
fCore::expose($result->fetchRow());
}
Primarily I'm interested in the sql modes. The default session one from fDatabase should be REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI, however I have a feeling somehow yours is getting NO_FIELD_OPTIONS too.
Will,
Sorry about that. I didn't realize you might want it from within php.
Here is the output:
<pre class="exposed">Array
(
[VERSION()] => 4.1.8a
[DATABASE()] => adhoc
)</pre><pre class="exposed">Array
(
[@@global.sql_mode] => {empty_string}
)</pre><pre class="exposed">Array
(
[@@session.sql_mode] => REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI
)</pre>
Unfortunately it looks like it is a bug in your version of MySQL. I am setting ANSI mode and it is incorrectly removing AUTO_INCREMENT from SHOW CREATE TABLE. This was fixed in v 4.1.15. You can check it out at http://bugs.mysql.com/bug.php?id=7977.
You can see if we can work around the bug by changing line 443 of fDatabase to:
$this->query("SET SQL_MODE = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE'");
Let me know if that works. If so, I'll roll it into the fDatabase changes I've been working on.
Thanks!
Did this end up working for you? If so, I'd like to include this in the upcoming fDatabase enhancements.
Yes, it did work. I apologize for not responding.
Thanks, Justin
Yes, it did work. I apologize for not responding.
Thanks, Justin