CakePHP Migrations - How to specify scale and precision - cakephp

I'm Running CakePhp 2.7 with Migrations Plugin and a Postgresql DB.
Creating a field of type 'number' and specifying length 15,4 (scale 15, precision 4 - or any length) does not actually create the field with that precision and/or scale.
...
'license_fee' => array(
'type' => 'number',
'null' => true,
'length' => '15,6',
'default' => 0
),
...
The field is created with the correct type (numeric) but with no scale/precision here is the Postgres description of the created field.
license_fee | numeric | default 0
What I was expecting to see is this
license_fee | numeric(15,6) | default 0
I also tried using 'type' => 'decimal' but same happened. This might not be supported by the migrations plugin but I just want to know if anyone knows for sure what's going on.

Found here: http://docs.phinx.org/en/latest/migrations.html
In order to create a : decimal(9,3)
$table->addColumn('distance', 'decimal', [
'default' => null,
'null' => false,
'precision'=>9,
'scale'=>3
]);

After further investigation and some help from Cake Development Corp. It turns out that the correct to way specify precision and scale is by using "limit" not "length" like I was attempting. So it should be like this:
'license_fee' => array(
'type' => 'number',
'null' => true,
'limit' => '15,6', //this is where I was wrong by using length
'default' => 0
),
This will work also if using 'type' => 'decimal' which is actually the same datatype. The end result is as expected:
license_fee | numeric(15,6) | default 0
I hope this useful for someone.

For 3.10 version:
$table->addColumn('name', ['type' => 'decimal', 'length' => 10, 'precision' => 3])
At /vendor/cakephp/cakephp/src/Database/Schema/TableSchema.php are the valid keys that can be used in a column:
$_columnKeys = [
'type' => null,
'baseType' => null,
'length' => null,
'precision' => null,
'null' => null,
'default' => null,
'comment' => null,
];

Related

cake migrations seed [Error] Object of class DateTimeImmutable could not be converted to string

I use command cake bake seed --data Users to created Seeds\UsersSeep.php with the following data type:
$data = [
[
'id' => 1,
'username' => 'pitocmsssss',
'email' => 'demo123#admin.com',
'amount' => 0,
'password' => '$2y$10$kcprj5VbJlJgcJXx3U5SJuFLmnlk5kNJKrpScZ8HQO6H7O9WgEHpi',
'created' =>
Cake\I18n\FrozenTime::__set_state(array(
'date' => '2020-04-01 07:14:22.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
'modified' =>
Cake\I18n\FrozenTime::__set_state(array(
'date' => '2022-08-22 04:03:58.000000',
'timezone_type' => 3,
'timezone' => 'UTC',
)),
],
...
];
When using the command cake migrations seed to insert data, the following error occurs:
using migration paths
/var/www/html/cake_myapp/config/Migrations using seed paths
/var/www/html/cake_myapp/config/Seeds using migration paths
/var/www/html/cake_myapp/config/Migrations using seed paths
/var/www/html/cake_myapp/config/Seeds using environment default using adapter mysql using database cake_tutorial
== UsersSeed: seeding 2022-08-23 07:51:53 error: [Error] Object of
class DateTimeImmutable could not be converted to string in
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php
on line 335 Stack Trace:
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/PdoAdapter.php:335
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php:180
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TimedOutputAdapter.php:102
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php:180
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Table.php:652
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Table.php:624
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Db/Table.php:682
/var/www/html/cake_myapp/config/Seeds/UsersSeed.php:216
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php:146
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php:416
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php:557
/var/www/html/cake_myapp/vendor/robmorgan/phinx/src/Phinx/Console/Command/SeedRun.php:102
/var/www/html/cake_myapp/vendor/cakephp/migrations/src/Command/Phinx/CommandTrait.php:37
/var/www/html/cake_myapp/vendor/cakephp/migrations/src/Command/Phinx/Seed.php:76
/var/www/html/cake_myapp/vendor/symfony/console/Command/Command.php:298
/var/www/html/cake_myapp/vendor/symfony/console/Application.php:1024
/var/www/html/cake_myapp/vendor/symfony/console/Application.php:299
/var/www/html/cake_myapp/vendor/symfony/console/Application.php:171
how to solve this problem? Thanks?

CakePHP migration re-organising column order

I have added new column using migrations.
This is my new added field
$table->addColumn('lastname', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
This column added after modified field. I want to change column order and want to put it after column name. How can I do it using migrations ?
You can use after in option, In adding time
$table->addColumn('firstname', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
'after' => 'name'
]);

CakePHP get model structure in controller action

I want to get the current model's structure from the controller, similar to the return of $this->modelName->read(null, id), but without the actual data in the record, just the structure.
Is this something Cake has built in?
I do not know of any such thing, although you can call, $this->ModelName->schema(); which will give output like:
array(
'id' => array(
'type' => 'integer',
'null' => false,
'default' => null,
'length' => (int) 11,
'key' => 'primary'
)
);
So you could use that to write something on your own like:
$schema = $this->Model->schema();
$values = array_fill ( 0 , count($schema), '' );
$model = array('Model' => array_combine(array_keys($schema), $values));

PDOException: Column not found

I have just taken over a Drupal 7.14 website that an old colleague made. I have logged in, but whenever I go to Admin > Content and click 'edit' to edit the content of any of my basic pages I get the following error message:
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'source' in 'where clause': SELECT url_alias.* FROM {url_alias} url_alias WHERE (source = :db_condition_placeholder_0) ; Array ( [:db_condition_placeholder_0] => node/1 ) in path_load() (line 419 of /home/sites/mediamatterstechnology.com/public_html/includes/path.inc).
Also if I go into Admin > Configuration > URL Aliases I get a similar message which is shown below:
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'language' in 'where clause': SELECT 1 FROM {url_alias} WHERE language <> :language LIMIT 0, 1; Array ( [:language] => und ) in path_admin_overview() (line 18 of /home/sites/mediamatterstechnology.com/public_html/modules/modules/path/path.admin.inc).
I would be so grateful for any help with this. I have been working on it for days, but I am a newbie with Drupal.
Drupal 5 and Drupal 6 don't have one (or two) of those fields. The reason why that database doesn't contain those fields could be:
The site was update from Drupal 5 / Drupal 6 to Drupal 7, and the update was not successful
The database got corrupted
A module removed the fields from the database
Those fields were manually removed
What you can do is adding the missing fields to the database, trying to first update the existing fields (in the case the site was updated from a previous Drupal version, and the update was not successful).
The following code should help.
// Drop indexes.
#db_drop_index('url_alias', 'src_language_pid');
#db_drop_unique_key('url_alias', 'dst_language_pid');
// Rename the fields, and increase their length to 255 characters.
#db_change_field('url_alias', 'src', 'source', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
#db_change_field('url_alias', 'dst', 'alias', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
if (db_field_exists('url_alias', 'language')) {
$spec = array(
'description' => "The language this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.",
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
);
db_change_field('url_alias', 'language', 'language', $spec);
db_update('url_alias')
->fields(array('language' => LANGUAGE_NONE))
->condition('language', '')
->execute();
}
else {
$spec = array(
'description' => "The language this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.",
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
);
db_add_field('url_alias', 'language', $spec);
}
// Add indexes back.
#db_add_index('url_alias', 'source_language_pid', array('source', 'language', 'pid'));
#db_add_index('url_alias', 'alias_language_pid', array('alias', 'language', 'pid'));
If this code doesn't get the missing fields, then it was not a failed update. In this case, you can use the following code, which should be used when you are sure the site was not updated from a Drupal version that is earlier than Drupal 7.
// Drop indexes.
#db_drop_index('url_alias', 'src_language_pid');
#db_drop_unique_key('url_alias', 'dst_language_pid');
$spec = array(
'description' => "The language this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.",
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
);
db_add_field('url_alias', 'language', $spec);
$spec = array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => ''
);
db_add_field('url_alias', 'source', $spec);
// Add indexes back.
#db_add_index('url_alias', 'source_language_pid', array('source', 'language', 'pid'));
#db_add_index('url_alias', 'alias_language_pid', array('alias', 'language', 'pid'));
The code has been written basing on the update code used from the System module when updating a previous Drupal version. The part I added is the one to create the database fields, since database fields are normally created during a Drupal installation.

Drupal 7 database API error "You have an error in your SQL syntax"

Using the following code:
db_update('nodesequence_nodes')
->fields(array(
'order' => 1,
))
->condition('nid', 1, '=')
->condition('nsid', 1, '=')
->execute();
I get the following error:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'order='1' WHERE (nid = '1') AND (nsid = '1')' at line 1: UPDATE
{nodesequence_nodes} SET order=:db_update_placeholder_0 WHERE (nid =
:db_condition_placeholder_0) AND (nsid = :db_condition_placeholder_1)
; Array ( [:db_update_placeholder_0] => 1
[:db_condition_placeholder_0] => 1 [:db_condition_placeholder_1] => 1
) in nodesequence_init() (line 13 of
/var/www/eventbooking2/sites/all/modules/nodesequence/nodesequence.module).
I apologize I can't offer any more insight, but I hope you can.
The simple db_update code seems to me that it should work but I can't figure out why it isn't.
The database schema:
$schema['nodesequence_nodes'] = array(
'description' => 'Relating nodesequences to their consituent nodes.',
'fields' => array(
'nsid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
'order' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
),
'primary key' => array('nsid', 'nid'),
);
You can't use the column named 'order' in a table as this is a reserved word. You need to change it to something else.
More info here http://dev.mysql.com/doc/refman/5.5/en/reserved-words.html take a look at table Table 9.2

Resources