# Zend\\Db\\TableGateway

The Table Gateway object is intended to provide an object that represents a table in a database, and
the methods of this object mirror the most common operations on a database table. In code, the
interface for such an object looks like this:

```php
interface Zend\Db\TableGateway\TableGatewayInterface
{
    public function getTable();
    public function select($where = null);
    public function insert($set);
    public function update($set, $where = null);
    public function delete($where);
}
```

There are two primary implementations of the `TableGatewayInterface` that are of the most useful:
`AbstractTableGateway` and `TableGateway`. The `AbstractTableGateway` is an abstract basic
implementation that provides functionality for `select()`, `insert()`, `update()`, `delete()`, as
well as an additional API for doing these same kinds of tasks with explicit SQL objects. These
methods are `selectWith()`, `insertWith()`, `updateWith()` and `deleteWith()`. In addition,
AbstractTableGateway also implements a "Feature" API, that allows for expanding the behaviors of the
base `TableGateway` implementation without having to extend the class with this new functionality.
The `TableGateway` concrete implementation simply adds a sensible constructor to the
`AbstractTableGateway` class so that out-of-the-box, `TableGateway` does not need to be extended in
order to be consumed and utilized to its fullest.

## Basic Usage

The quickest way to get up and running with Zend\\Db\\TableGateway is to configure and utilize the
concrete implementation of the `TableGateway`. The API of the concrete `TableGateway` is:

```php
class TableGateway extends AbstractTableGateway
{
 public $lastInsertValue;
 public $table;
 public $adapter;

 public function __construct($table, Adapter $adapter, $features = null, ResultSet
$resultSetPrototype = null, Sql $sql = null)

 /** Inherited from AbstractTableGateway */

    public function isInitialized();
    public function initialize();
    public function getTable();
    public function getAdapter();
    public function getColumns();
    public function getFeatureSet();
    public function getResultSetPrototype();
    public function getSql();
    public function select($where = null);
    public function selectWith(Select $select);
    public function insert($set);
    public function insertWith(Insert $insert);
    public function update($set, $where = null);
    public function updateWith(Update $update);
    public function delete($where);
    public function deleteWith(Delete $delete);
    public function getLastInsertValue();
}
```

The concrete `TableGateway` object practices constructor injection for getting dependencies and
options into the instance. The table name and an instance of an Adapter are all that is needed to
setup a working `TableGateway` object.

Out of the box, this implementation makes no assumptions about table structure or metadata, and when
`select()` is executed, a simple ResultSet object with the populated Adapter's Result (the
datasource) will be returned and ready for iteration.

```php
use Zend\Db\TableGateway\TableGateway;
$projectTable = new TableGateway('project', $adapter);
$rowset = $projectTable->select(array('type' => 'PHP'));

echo 'Projects of type PHP: ';
foreach ($rowset as $projectRow) {
 echo $projectRow['name'] . PHP_EOL;
}

// or, when expecting a single row:
$artistTable = new TableGateway('artist', $adapter);
$rowset = $artistTable->select(array('id' => 2));
$artistRow = $rowset->current();

var_dump($artistRow);
```

The `select()` method takes the same arguments as `Zend\Db\Sql\Select::where()` with the addition of
also being able to accept a closure, which in turn, will be passed the current Select object that is
being used to build the SELECT query. The following usage is possible:

```php
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Select;
$artistTable = new TableGateway('artist', $adapter);

// search for at most 2 artists who's name starts with Brit, ascending
$rowset = $artistTable->select(function (Select $select) {
 $select->where->like('name', 'Brit%');
 $select->order('name ASC')->limit(2);
});
```

## TableGateway Features

The Features API allows for extending the functionality of the base `TableGateway` object without
having to polymorphically extend the base class. This allows for a wider array of possible mixing
and matching of features to achieve a particular behavior that needs to be attained to make the base
implementation of `TableGateway` useful for a particular problem.

With the `TableGateway` object, features should be injected though the constructor. The constructor
can take Features in 3 different forms: as a single feature object, as a FeatureSet object, or as an
array of Feature objects.

There are a number of features built-in and shipped with Zend\\Db:

- GlobalAdapterFeature: the ability to use a global/static adapter without needing to inject it into
a `TableGateway` instance. This is more useful when you are extending the `AbstractTableGateway`
implementation:

```php
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\TableGateway\Feature;

class MyTableGateway extends AbstractTableGateway
{
   public function __construct()
   {
      $this->table = 'my_table';
         $this->featureSet = new Feature\FeatureSet();
         $this->featureSet->addFeature(new Feature\GlobalAdapterFeature());
         $this->initialize();
   }
}

// elsewhere in code, in a bootstrap
Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);

// in a controller, or model somewhere
$table = new MyTableGateway(); // adapter is statically loaded
```

- MasterSlaveFeature: the ability to use a master adapter for insert(), update(), and delete() while
using a slave adapter for all select() operations.

```php
$table = new TableGateway('artist', $adapter, new Feature\MasterSlaveFeature($slaveAdapter));
```

- MetadataFeature: the ability populate `TableGateway` with column information from a Metadata
object. It will also store the primary key information in case RowGatewayFeature needs to consume
this information.

```php
$table = new TableGateway('artist', $adapter, new Feature\MetadataFeature());
```

- EventFeature: the ability utilize a `TableGateway` object with Zend\\EventManager and to be able
to subscribe to various events in a `TableGateway` lifecycle.

```php
$table = new TableGateway('artist', $adapter, new Feature\EventFeature($eventManagerInstance));
```

- RowGatewayFeature: the ability for `select()` to return a ResultSet object that upon iteration
will return a `RowGateway` object for each row.

```php
$table = new TableGateway('artist', $adapter, new Feature\RowGatewayFeature('id'));
$results = $table->select(array('id' => 2));

$artistRow = $results->current();
$artistRow->name = 'New Name';
$artistRow->save();
```
