示例#1
0
 /**
  * Constructs the PostgreSQL adapter and sets the default port to 5432.
  *
  * @param array $config Configuration options for this class. Available options
  *                      defined by this class:
  *                      - `'host'`    : _string_ The IP or machine name where PostgreSQL is running,
  *                                      followed by a colon, followed by a port number or socket.
  *                                      Defaults to `'localhost:5432'`.
  *                      - `'schema'`  : _string_ The name of the database schema to use. Defaults to 'public'
  *                      - `'timezone'`: _stirng_ The database timezone. Defaults to `null`.
  */
 public function __construct($config = [])
 {
     $defaults = ['host' => 'localhost:5432', 'schema' => 'public', 'timezone' => null, 'classes' => ['dialect' => 'sql\\dialect\\PostgreSql'], 'handlers' => ['cast' => ['boolean' => function ($value, $options = []) {
         return $value === 't';
     }], 'datasource' => ['boolean' => function ($value, $options = []) {
         return $value ? 'true' : 'false';
     }, 'array' => function ($data) {
         $data = (array) $data;
         $result = [];
         foreach ($data as $value) {
             if (is_array($value)) {
                 $result[] = $this->_handlers['datasource']['array']($value);
             } else {
                 $value = str_replace('"', '\\"', $value);
                 if (!is_numeric($value)) {
                     $value = '"' . $value . '"';
                 }
                 $result[] = $value;
             }
         }
         return '{' . join(",", $result) . '}';
     }]]];
     $config = Set::merge($defaults, $config);
     parent::__construct($config + $defaults);
     $this->formatter('datasource', 'array', $this->_handlers['datasource']['array']);
 }
示例#2
0
 /**
  * Configures the schema class.
  *
  * @param array $config Possible options are:
  *                      - `'conventions'` _array_: Allow to override the default convention rules for generating
  *                                                 primary or foreign key as well as for table/collection names
  *                                                 from an entity class name.
  */
 public function config($config = [])
 {
     $defaults = ['conventions' => ['source' => function ($class) {
         $basename = substr(strrchr($class, '\\'), 1);
         return Inflector::underscore($basename);
     }, 'primaryKey' => function () {
         return 'id';
     }, 'foreignKey' => function ($class) {
         $pos = strrpos($class, '\\');
         $basename = substr($class, $pos !== false ? $pos + 1 : 0);
         return Inflector::underscore(Inflector::singularize($basename)) . '_id';
     }, 'fieldName' => function ($class) {
         $pos = strrpos($class, '\\');
         $basename = substr($class, $pos !== false ? $pos + 1 : 0);
         return Inflector::underscore(Inflector::singularize($basename));
     }, 'usingName' => function ($name) {
         return Inflector::singularize($name);
     }, 'getter' => function ($name) {
         return 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
     }, 'setter' => function ($name) {
         return 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
     }]];
     $config = Set::merge($defaults, $config);
     $this->_conventions = $config['conventions'];
 }
示例#3
0
 /**
  * Constructor.
  *
  * @param array $config Possible options are:
  *                      - `'classes'`     _array_  : The class dependencies.
  *                      - `'connection'`  _object_ : The connection instance.
  */
 public function __construct($config = [])
 {
     $defaults = ['classes' => ['schema' => 'chaos\\database\\Schema', 'model' => 'chaos\\Model'], 'connection' => null, 'fixtures' => []];
     $config = Set::merge($defaults, $config);
     $this->_classes = $config['classes'];
     $this->_connection = $config['connection'];
     $this->_fixtures = $config['fixtures'];
 }
示例#4
0
 /**
  * Constructor.
  *
  * @param array $config Possible options are:
  *                      - `'connection'`  _object_ : The connection instance.
  */
 public function __construct($config = [])
 {
     $defaults = ['connection' => null, 'model' => $this->_model, 'meta' => [], 'alters' => $this->_alters];
     $config = Set::merge($defaults, $config);
     $this->_connection = $config['connection'];
     $this->_meta = $config['meta'];
     $this->_alters = $config['alters'];
     $this->_model = $config['model'];
     $model = $this->_model;
     $model::config(['connection' => $this->connection()]);
 }
示例#5
0
 /**
  * Constructor
  *
  * @param array $config The config array. Possible values are:
  *                      - `'handlers'` _array_ : Some custom handlers.
  */
 public function __construct($config = [])
 {
     $defaults = ['meta' => [], 'handlers' => [], 'classes' => $this->_classes, 'error' => function ($name, $options, $meta = []) {
         return Text::insert($options['message'] ?: $this->message($name), $options);
     }];
     $config = Set::merge($defaults, $config);
     $this->_classes = $config['classes'];
     $this->set($config['handlers']);
     $this->error($config['error']);
     $this->meta($config['meta']);
 }
示例#6
0
 /**
  * Creates the database object and set default values for it.
  *
  * Options defined:
  *  - `'dns'`       : _string_ The full dsn connection url. Defaults to `null`.
  *  - `'database'`  : _string_ Name of the database to use. Defaults to `null`.
  *  - `'host'`      : _string_ Name/address of server to connect to. Defaults to 'localhost'.
  *  - `'username'`  : _string_ Username to use when connecting to server. Defaults to 'root'.
  *  - `'password'`  : _string_ Password to use when connecting to server. Defaults to `''`.
  *  - `'encoding'`  : _string_ The database character encoding.
  *  - `'persistent'`: _boolean_ If true a persistent connection will be attempted, provided the
  *                    adapter supports it. Defaults to `true`.
  *  - `'dialect'`       : _object_ A SQL dialect adapter
  *
  * @param  $config array Array of configuration options.
  * @return Database object.
  */
 public function __construct($config = [])
 {
     $defaults = ['classes' => ['cursor' => 'chaos\\database\\Cursor', 'schema' => 'chaos\\database\\Schema', 'dialect' => 'sql\\Dialect'], 'client' => null, 'connect' => true, 'meta' => ['key' => 'id', 'locked' => true], 'persistent' => true, 'host' => 'localhost', 'username' => 'root', 'password' => '', 'database' => null, 'encoding' => null, 'dsn' => null, 'options' => [], 'dialect' => null, 'handlers' => []];
     $config = Set::merge($defaults, $config);
     $this->_config = $config;
     $this->_classes = $this->_config['classes'] + $this->_classes;
     $this->_client = $this->_config['client'];
     unset($this->_config['client']);
     $this->_dialect = $config['dialect'];
     unset($this->_config['dialect']);
     $this->_handlers = Set::merge($this->_handlers(), $config['handlers']);
     if ($this->_dialect === null) {
         $dialect = $this->_classes['dialect'];
         $this->_dialect = new $dialect(['quoter' => function ($string) {
             return $this->quote($string);
         }, 'caster' => function ($value, $states = []) {
             $type = isset($states['type']) ? $states['type'] : gettype($value);
             if (is_array($type)) {
                 $type = call_user_func($type, $states['name']);
             }
             return $this->format('datasource', $type, $value);
         }]);
     }
     if ($this->_config['connect']) {
         $this->connect();
     }
     $handlers = $this->_handlers;
     $this->formatter('cast', 'id', $handlers['cast']['integer']);
     $this->formatter('cast', 'serial', $handlers['cast']['integer']);
     $this->formatter('cast', 'integer', $handlers['cast']['integer']);
     $this->formatter('cast', 'float', $handlers['cast']['float']);
     $this->formatter('cast', 'decimal', $handlers['cast']['decimal']);
     $this->formatter('cast', 'date', $handlers['cast']['date']);
     $this->formatter('cast', 'datetime', $handlers['cast']['datetime']);
     $this->formatter('cast', 'boolean', $handlers['cast']['boolean']);
     $this->formatter('cast', 'null', $handlers['cast']['null']);
     $this->formatter('cast', 'string', $handlers['cast']['string']);
     $this->formatter('cast', '_default_', $handlers['cast']['string']);
     $this->formatter('datasource', 'id', $handlers['datasource']['string']);
     $this->formatter('datasource', 'serial', $handlers['datasource']['string']);
     $this->formatter('datasource', 'integer', $handlers['datasource']['string']);
     $this->formatter('datasource', 'float', $handlers['datasource']['string']);
     $this->formatter('datasource', 'decimal', $handlers['datasource']['string']);
     $this->formatter('datasource', 'date', $handlers['datasource']['date']);
     $this->formatter('datasource', 'datetime', $handlers['datasource']['datetime']);
     $this->formatter('datasource', 'boolean', $handlers['datasource']['boolean']);
     $this->formatter('datasource', 'null', $handlers['datasource']['null']);
     $this->formatter('datasource', 'string', $handlers['datasource']['quote']);
     $this->formatter('datasource', 'object', $handlers['datasource']['object']);
     $this->formatter('datasource', '_default_', $handlers['datasource']['quote']);
 }
示例#7
0
 /**
  * Expands a collection of entities by adding their related data.
  *
  * @param  mixed $collection The collection to expand.
  * @return array             The collection of related entities.
  */
 public function embed(&$collection, $options = [])
 {
     $options = Set::merge(['fetchOptions' => ['collector' => $this->_collector($collection)]], $options);
     $name = $this->name();
     $through = $this->through();
     $using = $this->using();
     $from = $this->from();
     $relThrough = $from::relation($through);
     $middle = $relThrough->embed($collection, $options);
     $pivot = $relThrough->to();
     $relUsing = $pivot::schema()->relation($using);
     $related = $relUsing->embed($middle, $options);
     $this->_cleanup($collection);
     $fromKey = $this->keys('from');
     $indexes = $this->_index($related, $this->keys('to'));
     foreach ($collection as $index => $entity) {
         if (is_object($entity)) {
             foreach ($entity->{$through} as $key => $item) {
                 if (isset($item->{$using})) {
                     $value = $item->{$using};
                     if ($entity instanceof Model) {
                         $entity->__get($name);
                         // Too Many Magic Kill The Magic.
                     } else {
                         $entity->{$name}[] = $value;
                     }
                 }
             }
         } else {
             foreach ($entity[$through] as $key => $item) {
                 if (isset($indexes[$item[$fromKey]])) {
                     $collection[$index][$name][] = $related[$indexes[$item[$fromKey]]];
                     $collection[$index][$through][$key][$using] = $related[$indexes[$item[$fromKey]]];
                 }
             }
         }
     }
     return $related;
 }
示例#8
0
 /**
  * Expands a collection of entities by adding their related data.
  *
  * @param  mixed $collection The collection to expand.
  * @param  array $options    The embedging options.
  * @return array             The collection of related entities.
  */
 public function embed(&$collection, $options = [])
 {
     $indexes = $this->_index($collection, $this->keys('from'));
     $related = $this->_find(array_keys($indexes), Set::merge(['fetchOptions' => ['collector' => $this->_collector($collection)]], $options));
     $name = $this->name();
     $this->_cleanup($collection);
     foreach ($related as $index => $entity) {
         if (is_object($entity)) {
             $value = $entity->{$this->keys('to')};
             if (isset($indexes[$value])) {
                 $source = $collection[$indexes[$value]];
                 $source->{$name}[] = $entity;
             }
         } else {
             $value = $entity[$this->keys('to')];
             if (isset($indexes[$value])) {
                 $collection[$indexes[$value]][$name][] = $entity;
             }
         }
     }
     return $related;
 }
示例#9
0
 /**
  * Configures the meta for use.
  *
  * @param array $config Possible options are:
  *                      - `'connection'`  _object_ : The connection instance (defaults to `null`).
  *                      - `'source'`      _string_ : The source name (defaults to `null`).
  *                      - `'model'`       _string_ : The fully namespaced model class name (defaults to `null`).
  *                      - `'locked'`      _boolean_: set the ability to dynamically add/remove fields (defaults to `false`).
  *                      - `'primaryKey'`  _array_  : The primary key value (defaults to `id`).
  *                      - `'fields'`      _array_  : array of field definition where keys are field names and values are arrays
  *                                                   with the following keys. All properties are optionnal except the `'type'`:
  *                                                   - `'type'`       _string_ : the type of the field.
  *                                                   - `'default'`    _mixed_  : the default value (default to '`null`').
  *                                                   - `'null'`       _boolean_: allow null value (default to `'null'`).
  *                                                   - `'length'`     _integer_: the length of the data (default to `'null'`).
  *                                                   - `'precision'`  _integer_: the precision (for decimals) (default to `'null'`).
  *                                                   - `'use'`        _string_ : the database type to override the associated type for
  *                                                                               this type (default to `'null'`).
  *                                                   - `'serial'`     _string_ : autoincremented field (default to `'null'`).
  *                                                   - `'primary'`    _boolead_: primary key (default to `'null'`).
  *                                                   - `'unique'`     _boolead_: unique key (default to `'null'`).
  *                                                   - `'foreignKey'` _string_ : foreign key (default to `'null'`).
  *                      - `'meta'`        _array_  : array of meta definitions for the schema. The definitions are related to
  *                                                   the datasource. For the MySQL adapter the following options are available:
  *                                                   - `'charset'`    _string_: the charset value to use for the table.
  *                                                   - `'collate'`    _string_: the collate value to use for the table.
  *                                                   - `'engine'`     _stirng_: the engine value to use for the table.
  *                                                   - `'tablespace'` _string_: the tablespace value to use for the table.
  *                      - `'handlers'`    _array_  : casting handlers.
  *                      - `'conventions'` _object_ : The naming conventions instance.
  *                      - `'classes'`     _array_  : The class dependencies.
  */
 public function __construct($config = [])
 {
     $defaults = ['connection' => null, 'source' => null, 'model' => null, 'locked' => true, 'fields' => [], 'meta' => [], 'handlers' => [], 'conventions' => null, 'classes' => $this->_classes];
     $config = Set::merge($defaults, $config);
     $this->_classes = $config['classes'];
     $this->_connection = $config['connection'];
     $this->_locked = $config['locked'];
     $this->_meta = $config['meta'];
     $this->_handlers = Set::merge($config['handlers'], $this->_handlers());
     $this->_conventions = $config['conventions'] ?: new Conventions();
     $config += ['primaryKey' => $this->_conventions->apply('primaryKey')];
     $this->_fields = $config['fields'];
     $this->_source = $config['source'];
     $this->_model = $config['model'];
     $this->_primaryKey = $config['primaryKey'];
     foreach ($config['fields'] as $key => $value) {
         $this->_fields[$key] = $this->_initField($value);
     }
     if ($this->_connection) {
         $this->_formatters = $this->_connection->formatters();
     }
     $handlers = $this->_handlers;
     $this->formatter('array', 'id', $handlers['array']['integer']);
     $this->formatter('array', 'serial', $handlers['array']['integer']);
     $this->formatter('array', 'integer', $handlers['array']['integer']);
     $this->formatter('array', 'float', $handlers['array']['float']);
     $this->formatter('array', 'decimal', $handlers['array']['float']);
     $this->formatter('array', 'date', $handlers['array']['date']);
     $this->formatter('array', 'datetime', $handlers['array']['date']);
     $this->formatter('array', 'boolean', $handlers['array']['boolean']);
     $this->formatter('array', 'null', $handlers['array']['null']);
     $this->formatter('array', '_default_', $handlers['array']['string']);
 }
示例#10
0
 /**
  * Constructs the MySQL adapter and sets the default port to 3306.
  *
  * @param array $config Configuration options for this class. Available options
  *                      defined by this class:
  *                      - `'host'`: _string_ The IP or machine name where MySQL is running,
  *                                  followed by a colon, followed by a port number or socket.
  *                                  Defaults to `'localhost:3306'`.
  */
 public function __construct($config = [])
 {
     $defaults = ['host' => 'localhost:3306', 'classes' => ['dialect' => 'sql\\dialect\\MySql'], 'handlers' => []];
     $config = Set::merge($defaults, $config);
     parent::__construct($config);
 }
示例#11
0
 /**
  * Gets all entities attached to a collection en entities.
  *
  * @param  mixed  $id An id or an array of ids.
  * @return object     A collection of items matching the id/ids.
  */
 protected function _find($id, $options = [])
 {
     $defaults = ['query' => [], 'fetchOptions' => []];
     $options += $defaults;
     $fetchOptions = $options['fetchOptions'];
     unset($options['fetchOptions']);
     if ($this->link() !== static::LINK_KEY) {
         throw new ChaosException("This relation is not based on a foreign key.");
     }
     $to = $this->to();
     if (!$id) {
         $collector = isset($fetchOptions['collector']) ? $fetchOptions['collector'] : null;
         return $to::create([], ['type' => 'set', 'collector' => $collector]);
     }
     if (is_array($id) && count($id) === 1) {
         $id = reset($id);
     }
     $query = Set::merge($options['query'], ['conditions' => [$this->keys('to') => $id]]);
     return $to::all($query, $fetchOptions);
 }
示例#12
0
 /**
  * Sets the relations to retrieve.
  *
  * @param  array  $embed The relations to load with the query.
  * @return object        Returns `$this`.
  */
 public function embed($embed = null, $conditions = [])
 {
     if (!$embed) {
         return $this->_embed;
     }
     if (!is_array($embed)) {
         $embed = [$embed => $conditions];
     }
     $embed = Set::normalize($embed);
     $this->_embed = Set::merge($this->_embed, $embed);
     return $this;
 }
示例#13
0
文件: Model.php 项目: ssgonchar/chaos
 /**
  * Instantiates a new record or document object, initialized with any data passed in. For example:
  *
  * ```php
  * $post = Posts::create(['title' => 'New post']);
  * echo $post->title; // echoes 'New post'
  * $success = $post->save();
  * ```
  *
  * Note that while this method creates a new object, there is no effect on the database until
  * the `save()` method is called.
  *
  * In addition, this method can be used to simulate loading a pre-existing object from the
  * database, without actually querying the database:
  *
  * ```php
  * $post = Posts::create(['id' => $id, 'moreData' => 'foo'], ['exists' => true]);
  * $post->title = 'New title';
  * $success = $post->save();
  * ```
  *
  * This will create an update query against the object with an ID matching `$id`. Also note that
  * only the `title` field will be updated.
  *
  * @param  array  $data    Any data that this object should be populated with initially.
  * @param  array  $options Options to be passed to item.
  *                         - `'type'`       _string_ : can be `'entity'` or `'set'`. `'set'` is used if the passed data represent a collection
  *                           of entities. Default to `'entity'`.
  *                         - `'exists'`     _mixed_  : corresponds whether the entity is present in the datastore or not.
  *                         - `'autoreload'` _boolean_: sets the specific behavior when exists is `null`. A '`true`' value will perform a
  *                           reload of the entity from the datasource. Default to `'true'`.
  *                         - `'defaults'`   _boolean_: indicates whether the entity needs to be populated with their defaults values on creation.
  *                         - `'model'`      _string_ : the model to use for instantiating the entity. Can be useful for implementing
  *                                                     som Single Table Inheritance.
  * @return object          Returns a new, un-saved record or document object. In addition to
  *                         the values passed to `$data`, the object will also contain any values
  *                         assigned to the `'default'` key of each field defined in the schema.
  */
 public static function create($data = [], $options = [])
 {
     $defaults = ['type' => 'entity', 'exists' => false, 'model' => static::class];
     $options += $defaults;
     $options['defaults'] = !$options['exists'];
     if ($options['defaults'] && $options['type'] === 'entity') {
         $data = Set::merge(Set::expand(static::schema()->defaults()), $data);
     }
     $type = $options['type'];
     $class = $type === 'entity' ? $options['model'] : static::$_classes[$options['type']];
     $options = ['data' => $data] + $options;
     return new $class($options);
 }
示例#14
0
 /**
  * Constructs the Sqlite adapter and sets the default port to 3306.
  *
  * @param array $config Configuration options for this class. Available options:
  *                      - `'database'` _string_ : database path. Defaults to `':memory:'`.
  */
 public function __construct($config = [])
 {
     $defaults = ['database' => ':memory:', 'classes' => ['dialect' => 'sql\\dialect\\Sqlite'], 'handlers' => []];
     $config = Set::merge($defaults, $config);
     parent::__construct($config);
 }