Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Data Model Questions /

Database always recreating Decimal fields on DB rebuild (dev/build) despite fields not changing...


Reply


3 Posts   767 Views

Avatar
vwd

Community Member, 159 Posts

3 November 2011 at 1:41pm

Edited: 03/11/2011 1:43pm

Hi,

I've noticed that a couple of Decimal fields now always are highlighted as changing/being updated every time I do a dev/build.

They are 2 fields from [url=https://github.com/ajshort/silverstripe-addressable/blob/master/code/Geocodable.php]Geocodable.php[/url] - Lat/Lng which I changed a while ago from from Floats to Decimal(9,6)

Current Code:

   public function extraStatics() {
      return array('db' => array(
         'Lat' => 'Decimal(9,6)',
         'Lng' => 'Decimal(9,6)'
      ));
   }

Old code:

   public function extraStatics() {
      return array('db' => array(
         'Lat' => 'Float',
         'Lng' => 'Float
      ));
   }

Since that change, every time I do a dev/build I get the following output from the build:

Building database mydb_ss using MySQL 5.5.9

Creating database tables

PageComment
SiteConfig
Field SiteConfig.Lat: changed to decimal(9,6) not null default 0 (from decimal(9,6) not null default 0.000000)
Field SiteConfig.Lng: changed to decimal(9,6) not null default 0 (from decimal(9,6) not null default 0.000000)
SiteTree
<snip>

Database build completed!

Note that I haven't change the DB Field types between rebuilds.

After a bit of investigation - I've found that the problem might be in Decimal.php. The way the field is created, it appears to be passing in a double where it was requiring a string equivalent of $defaultField in the requireField(...) method. So there is always a discrepancy between the DB's default value for the Decimal(9,6) field (0.000000) and what it is being compared with in Sapphire which defaults to "0".

The code that seems to work:

<?php
/**
* Represents a Decimal field.
* @package sapphire
* @subpackage model
*/
class Decimal extends DBField {
   protected $wholeSize, $decimalSize, $defaultValue;
   
<snip>

   function requireField() {
      $beforeDecimal = $this->wholeSize - $this->decimalSize;
      $formatString = "%" . $beforeDecimal . "." . $this->decimalSize . "f";
      $defaultStr = sprintf($formatString, $this->defaultValue);
      $parts=Array('datatype'=>'decimal', 'precision'=>"$this->wholeSize,$this->decimalSize", 'default'=>$defaultStr, 'arrayValue'=>$this->arrayValue);
      $values=Array('type'=>'decimal', 'parts'=>$parts);
      DB::requireField($this->tableName, $this->name, $values);
}
   
<snip>

   public function nullValue() {
      $beforeDecimal = $this->wholeSize - $this->decimalSize;
      $formatString = "%" . $beforeDecimal . "." . $this->decimalSize . "f";
      $nullValueStr = sprintf($formatString, (double)0);
      return $nullValueStr;
   }
<snip>
?>

So is this a genuine bug that needs to be reported? I'm trying to get the unit tests running to see if this change has broken anything else.

Thanks,
VWD.

Avatar
Willr

Forum Moderator, 5513 Posts

4 November 2011 at 6:35pm

Yes it is a bug, if it hasn't been reported yet on open.silverstripe.org I recommend posting it to that and submitting your fix as a pull request to github for sapphire.

Avatar
MarcelKlomp

Community Member, 5 Posts

18 November 2011 at 7:24am

Awesome VWD. Had seen it as well in this project I'm working on, figured what it could be but no time to look into it (yet plenty of time to be bugged by it). Applied your fix et voila. Thanks!