1   Getting started

1.1   Setup

There are some prerequesites, you should have composer. Sources will be in folder src/VendorName/ApplicationName. Add this autoload to composer.json

{
    "autoload": {
        "psr-4": { "VendorName\\ApplicationName\\": "src/VendorName/ApplicationName"}
    }
}

1.2   Installation

Define the following requirement for your project : composer require ccmbenchmark/ting

1.3   Setup database

For this tutorial we are using world database which you need to install into a MySQL. You can refer to the official guide.

1.4   Creating repositories

world database is composed of three tables :

City
ID int(11)
Name char(35)
CountryCode char(3)
Population int(11)
Country
Code int(3)
Name char(52)
Region char(26)
Population int(11)
CountryLanguage
CountryCode char(3)
Language char(30)
Percentage float(4, 1)

Note

In this tutorial we don’t take all columns of tables

1.5   Creating City repository

src/VendorName/ApplicationName/Repository/City.php
<?php

namespace VendorName\ApplicationName\Repository;

use CCMBenchmark\Ting\Exception;
use CCMBenchmark\Ting\Repository\Metadata;
use CCMBenchmark\Ting\Repository\MetadataInitializer;
use CCMBenchmark\Ting\Repository\Repository;
use CCMBenchmark\Ting\Serializer\SerializerFactoryInterface;

class City extends Repository implements MetadataInitializer
{

    /**
     * @param SerializerFactoryInterface $serializerFactory
     *
     * @return Metadata
     * @throws Exception
     */
    public static function initMetadata(SerializerFactoryInterface $serializerFactory, array $options = [])
    {
        $metadata = new Metadata($serializerFactory);
        $metadata->setEntity(\VendorName\ApplicationName\Entity\City::class);
        $metadata->setConnectionName('main');
        $metadata->setDatabase('world');
        $metadata->setTable('City');

        $metadata
            ->addField([
                'primary'       => true,
                'autoincrement' => true,
                'fieldName'     => 'id',
                'columnName'    => 'ID',
                'type'          => 'int'
            ])
            ->addField([
                'fieldName'  => 'name',
                'columnName' => 'Name',
                'type'       => 'string'
            ])
            ->addField([
                'fieldName'  => 'countryCode',
                'columnName' => 'CountryCode',
                'type'       => 'string'
            ])
            ->addField([
                'fieldName'  => 'population',
                'columnName' => 'Population',
                'type'       => 'int'
            ]);

        return $metadata;
    }
}

1.6   Creating Country repository

src/VendorName/ApplicationName/Repository/Country.php
<?php

namespace VendorName\ApplicationName\Repository;

use CCMBenchmark\Ting\Exception;
use CCMBenchmark\Ting\Repository\Metadata;
use CCMBenchmark\Ting\Repository\MetadataInitializer;
use CCMBenchmark\Ting\Repository\Repository;
use CCMBenchmark\Ting\Serializer\SerializerFactoryInterface;

class Country extends Repository implements MetadataInitializer
{

    /**
     * @param SerializerFactoryInterface $serializerFactory
     *
     * @return Metadata
     * @throws Exception
     */
    public static function initMetadata(SerializerFactoryInterface $serializerFactory, array $options = [])
    {
        $metadata = new Metadata($serializerFactory);
        $metadata->setEntity(\VendorName\ApplicationName\Entity\Country::class);
        $metadata->setConnectionName('main');
        $metadata->setDatabase('world');
        $metadata->setTable('Country');

        $metadata
            ->addField([
                'primary'       => true,
                'fieldName'     => 'code',
                'columnName'    => 'Code',
                'type'          => 'string'
            ])
            ->addField([
                'fieldName'  => 'name',
                'columnName' => 'Name',
                'type'       => 'string'
            ])
            ->addField([
                'fieldName'  => 'region',
                'columnName' => 'Region',
                'type'       => 'string'
            ])
            ->addField([
                'fieldName'  => 'population',
                'columnName' => 'Population',
                'type'       => 'int'
            ]);

        return $metadata;
    }
}

1.7   Creating CountryLanguage repository

src/VendorName/ApplicationName/Repository/CountryLanguage.php
<?php

namespace VendorName\ApplicationName\Repository;

use CCMBenchmark\Ting\Exception;
use CCMBenchmark\Ting\Repository\Metadata;
use CCMBenchmark\Ting\Repository\MetadataInitializer;
use CCMBenchmark\Ting\Repository\Repository;
use CCMBenchmark\Ting\Serializer\SerializerFactoryInterface;

class CountryLanguage extends Repository implements MetadataInitializer
{

    /**
     * @param SerializerFactoryInterface $serializerFactory
     *
     * @return Metadata
     * @throws Exception
     */
    public static function initMetadata(SerializerFactoryInterface $serializerFactory, array $options = [])
    {
        $metadata = new Metadata($serializerFactory);
        $metadata->setEntity(\VendorName\ApplicationName\Entity\Country::class);
        $metadata->setConnectionName('main');
        $metadata->setDatabase('world');
        $metadata->setTable('CountryLanguage');

        $metadata
            ->addField([
                'fieldName'     => 'countryCode',
                'columnName'    => 'CountryCode',
                'type'          => 'string'
            ])
            ->addField([
                'fieldName'  => 'language',
                'columnName' => 'Language',
                'type'       => 'string'
            ])
            ->addField([
                'fieldName'  => 'percentage',
                'columnName' => 'Percentage',
                'type'       => 'double'
            ]);

        return $metadata;
    }
}

1.8   Database connection settings

src/VendorName/ApplicationName/bootstrap.php
<?php

namespace VendorName\ApplicationName;

require __DIR__ . '/../../../vendor/autoload.php';

$services = new \CCMBenchmark\Ting\Services();
$services->get('ConnectionPool')->setConfig([
    'main' => [
        'namespace' => '\CCMBenchmark\Ting\Driver\Mysqli',
        'master' => [
            'host'      => 'localhost',
            'user'      => 'root',
            'password'  => '',
            'port'      => 3306,
        ]
    ]
]);

1.9   Repositories settings

To set the directory of repository we append to bootstrap.php

src/VendorName/ApplicationName/bootstrap.php
<?php

$services
    ->get('MetadataRepository')
    ->batchLoadMetadata('VendorName\ApplicationName\Repository', __DIR__ . '/Repository/*.php');

1.10   Creating entities

Previously we created the repository and linked each one with one entity : $metadata->setEntity(\VendorName\ApplicationName\Entity\Country::class); Now we create entity for each repository.

src/VendorName/ApplicationName/Entity/City.php
<?php

namespace VendorName\ApplicationName\Entity;

use CCMBenchmark\Ting\Entity\NotifyProperty;
use CCMBenchmark\Ting\Entity\NotifyPropertyInterface;

class City implements NotifyPropertyInterface
{
    use NotifyProperty;

    private $id;
    private $name = '';
    private $countryCode = '';
    private $population = 0;

    /**
     * @param int $id
     */
    public function setId($id)
    {
        $this->propertyChanged('id', $this->id, (int) $id);
        $this->id = (int) $id;
    }

    /**
     * @return int|null
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param string $name
     */
    public function setName($name)
    {
        $this->propertyChanged('name', $this->name, (string) $name);
        $this->name = (string) $name;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $countryCode
     */
    public function setCountryCode($countryCode)
    {
        $this->propertyChanged('countryCode', $this->countryCode, (string) $countryCode);
        $this->countryCode = (string) $countryCode;
    }

    /**
     * @return string
     */
    public function getCountryCode()
    {
        return $this->countryCode;
    }

    /**
     * @param int $population
     */
    public function setPopulation($population)
    {
        $this->propertyChanged('population', $this->population, (int) $population);
        $this->population = (int) $population;
    }

    /**
     * @return int
     */
    public function getPopulation()
    {
        return $this->population;
    }
}
src/VendorName/ApplicationName/Entity/Country.php
<?php

namespace VendorName\ApplicationName\Entity;

use CCMBenchmark\Ting\Entity\NotifyProperty;
use CCMBenchmark\Ting\Entity\NotifyPropertyInterface;

class Country implements NotifyPropertyInterface
{
    use NotifyProperty;

    private $code = '';
    private $name = '';
    private $region = '';
    private $population = 0;

    /**
     * @param string $code
     */
    public function setCode($code)
    {
        $this->propertyChanged('code', $this->code, (string) $code);
        $this->code = (string) $code;
    }

    /**
     * @return string
     */
    public function getCode()
    {
        return $this->code;
    }

    /**
     * @param string $name
     */
    public function setName($name)
    {
        $this->propertyChanged('name', $this->name, (string) $name);
        $this->name = (string) $name;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $region
     */
    public function setRegion($region)
    {
        $this->propertyChanged('region', $this->region, (string) $region);
        $this->region = (string) $region;
    }

    /**
     * @return string
     */
    public function getRegion()
    {
        return $this->region;
    }

    /**
     * @param int $population
     */
    public function setPopulation($population)
    {
        $this->propertyChanged('population', $this->population, (int) $population);
        $this->population = (int) $population;
    }

    /**
     * @return int
     */
    public function getPopulation()
    {
        return $this->population;
    }
}
src/VendorName/ApplicationName/Entity/CountryLanguage.php
<?php

namespace VendorName\ApplicationName\Entity;

use CCMBenchmark\Ting\Entity\NotifyProperty;
use CCMBenchmark\Ting\Entity\NotifyPropertyInterface;

class CountryLanguage implements NotifyPropertyInterface
{
    use NotifyProperty;

    private $countryCode = '';
    private $language = '';
    private $percentage = 0.0;

    /**
     * @param string $countryCode
     */
    public function setCountryCode($countryCode)
    {
        $this->propertyChanged('countryCode', $this->countryCode, (string) $countryCode);
        $this->countryCode = (string) $countryCode;
    }

    /**
     * @return string
     */
    public function getCountryCode()
    {
        return $this->countryCode;
    }

    /**
     * @param string $language
     */
    public function setLanguage($language)
    {
        $this->propertyChanged('language', $this->language, (string) $language);
        $this->language = (string) $language;
    }

    /**
     * @return string
     */
    public function getLanguage()
    {
        return $this->language;
    }

    /**
     * @param double $percentage
     */
    public function setPercentage($percentage)
    {
        $this->propertyChanged('percentage', $this->percentage, (double) $percentage);
        $this->percentage = (double) $percentage;
    }

    /**
     * @return double
     */
    public function getPercentage()
    {
        return $this->percentage;
    }
}

Now repositories and entities are configured we can do queries.

1.11   You can now use Ting

src/VendorName/ApplicationName/bootstrap.php
$debug = new \CCMBenchmark\Ting\Util\Debug();

$cityRepository = $services->get('RepositoryFactory')
    ->get(\VendorName\ApplicationName\Repository\City::class);

$debug->dump($cityRepository->get(3));