PHP Classes

File: DATA/SQLDecimal.php

Recommend this page to a friend!
  Classes of Martin Alterisio   DATA   DATA/SQLDecimal.php   Download  
File: DATA/SQLDecimal.php
Role: Class source
Content type: text/plain
Description: ANSI SQL arbitrary size number with decimals data type representation.
Class: DATA
Access data stored in MySQL tables like arrays
Author: By
Last change: + anonymous access
Date: 16 years ago
Size: 5,597 bytes
 

Contents

Class file image Download
<?php
/**
 * @package DATA
 */

/**
 * ANSI SQL arbitrary size number with decimals data type representation.
 *
 * When inboxing, if the field cannot hold the desired value
 * {@link DATA_InvalidDecimal} is thrown.
 *
 * @todo Arbitrary math implementation.
 */
class DATA_SQLDecimal extends DATA_SQLType implements DATA_Number {
   
/**
     * How many digits can hold this field.
     * @var int
     */
   
protected $precision;
   
/**
     * How many digits after the decimal point this field has.
     * @var int
     */
   
protected $scale;
   
/**
     * The stored number.
     * @var mixed
     */
   
protected $number;
   
   
/**
     * Construct a sql numeric type with requested precision, scale and initial value (optional).
     *
     * Throws {@link DATA_InvalidDecimal} when number to be stored is bigger than allowed.
     *
     * @param int $precision How many digits can hold this field.
     * @param int $scale How many digits after the decimal point this field has.
     * @param mixed $number The stored number.
     */
   
public function __construct($nullable, $precision, $scale, $number = '0') {
       
$this->precision = $precision;
       
$this->scale = $scale;
       
$this->setNumber($number);
       
parent::__construct($nullable, is_null($number));
    }
   
   
/**
     * Returns the field precision.
     *
     * @return int Field precision.
     */
   
public function getPrecision() {
        return
$this->precision;
    }
   
   
/**
     * Returns the field scale.
     *
     * @return int Field scale.
     */
   
public function getScale() {
        return
$this->scale;
    }
   
   
/**
     * Returns the stored number.
     *
     * @return mixed The stored number.
     */
   
public function getNumber() {
        return
$this->number;
    }
   
   
/**
     * Returns the stored number as an integer.
     *
     * @return int The stored number.
     */
   
public function getNumberAsInt() {
        return (int)
$this->number;
    }
   
   
/**
     * Returns the stored number as a float.
     *
     * @return float The stored number.
     */
   
public function getNumberAsFloat() {
        return (float)
$this->number;
    }
   
   
/**
     * Sets the stored number.
     *
     * Throws {@link DATA_InvalidDecimal} when number to be stored is bigger than allowed.
     *
     * @param mixed $number The stored number.
     */
   
public function setNumber($number) {
        if (!
$this->checkNumber($number)) {
            throw new
DATA_InvalidDecimal($this->precision, $this->scale, $number);
        }
       
$this->number = $number;
       
$this->setNotNull();
    }
   
    public function
setNull() {
       
parent::setNull();
       
$this->number = null;
    }
   
    public function
__toString() {
        return
number_format($this->number, $this->scale, ".", "");
    }
   
   
/**
     * Adds this number to another and returns the result.
     *
     * Throws {@link DATA_InvalidDecimal}.
     *
     * @param DATA_Number $other The number to add.
     * @return DATA_SQLNumeric The result.
     */
   
public function add(DATA_Number $other) {
        return new
DATA_SQLNumeric($this->isNullable(), $this->precision, $this->scale, $this->number + $other->getNumber());
    }
   
   
/**
     * Substracts this number to another and returns the result.
     *
     * Throws {@link DATA_InvalidDecimal}.
     *
     * @param DATA_Number $other The number to substract.
     * @return DATA_SQLNumeric The result.
     */
   
public function substract(DATA_Number $other) {
        return new
DATA_SQLNumeric($this->isNullable(), $this->precision, $this->scale, $this->number - $other->getNumber());
    }
   
   
/**
     * Multiplies this number by another and returns the result.
     *
     * Throws {@link DATA_InvalidDecimal}.
     *
     * @param DATA_Number $other The number to multiply by.
     * @return DATA_SQLNumeric The result.
     */
   
public function multiply(DATA_Number $other) {
        return new
DATA_SQLNumeric($this->isNullable(), $this->precision, $this->scale, $this->number * $other->getNumber());
    }
   
   
/**
     * Divides this number by another and returns the result.
     *
     * Throws {@link DATA_InvalidDecimal}.
     *
     * @param DATA_Number $other The number to divide by.
     * @return DATA_SQLNumeric The result.
     */
   
public function divide(DATA_Number $other) {
        return new
DATA_SQLNumeric($this->isNullable(), $this->precision, $this->scale, (int)($this->number / $other->getNumber()));
    }
   
   
/**
     * Checks if a number could fit inside this field
     *
     * @param mixed $number The number.
     * @return bool True if the value fits in this field.
     */
   
protected function checkNumber($number) {
        if (
is_float($number)) {
           
$number = number_format($number, $this->scale+1, "", ".");
        } else {
           
$number = (string)$number;
        }
       
$regexp = '[+-]?';
        if (
$this->precision > $this->scale) {
           
$regexp .= '[0-9]{1,' . ($this->precision - $this->scale) . '}';
        } else {
           
$regexp .= '0';
        }
        if (
$this->scale > 0) {
           
$regexp .= '(\\.[0-9]{1,' . $this->scale . '})?';
        }
        if (
preg_match("/^{$regexp}$/", $number)) {
            return
true;
        }
        return
false;
    }
}
?>