PHP code example of genesis / sql-data-mods

1. Go to this page and download the library: Download genesis/sql-data-mods library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

genesis / sql-data-mods example snippets



use Behat\Testwork\Hook\Scope\BeforeSuiteScope;
use Genesis\SQLExtensionWrapper\DataModSQLContext;
use Genesis\SQLExtensionWrapper\BaseProvider;

class FeatureContext
{
    /**
     * @BeforeSuite
     */
    public static function loadDataModSQLContext(BeforeSuiteScope $scope)
    {
        BaseProvider::setCredentials([
            'mssql' => [
                'engine' => 'dblib',
                'name' => 'databaseName',
                'schema' => 'dbo',
                'prefix' => 'dev_',
                'host' => 'myhost',
                'port' => '1433',
                'username' => 'myUsername',
                'password' => 'myPassword'
            ]
        ]);

        // Default path is \\DataMod\\ which points to features/DataMod/, override this way.
        DataModSQLContext::setDataModMapping([
            '*' => '\\Custom\\DataMod\\'
        ]);

        DataModSQLContext::setDomainModMapping([
            '*' => '\\Custom\\DomainMod\\'
        ]);

        $scope->getEnvironment()->registerContextClass(
            DataModSQLContext::class,
            ['debug' => false]
        );
    }
}

# User.php


namespace QuickPack\DataMod\User;

use Genesis\DataMods\Traits\SimplifiedDeclarations;
use Genesis\SQLExtensionWrapper\Contract\DataModInterface;
use Genesis\SQLExtensionWrapper\BaseProvider;

class User extends BaseProvider
{
    // Provides an alternate syntax for declarations.
    use SimplifiedDeclarations;

    /**
     * Returns the base table to interact with.
     */
    private static $baseTable = 'MySuperApplication.MyUsersNew';

    /**
     * Returns the data mapping for the base table. This is the data that is allowed to be passed in
     * to the data mod. <input> => <mapping>
     *
     * Note any column mapped to '*' is excluded from the queries and only is a part of the data passed around.
     *
     * @return array
     */
    private static $dataMapping = [
        'id' => 'user_id',
        'name' => 'f_name',
        'email' => 'electronic_address',
        'dateOfBirth' => 'd_o_b',
        'gender' => 'gender',
        'status' => 'real_status',
        'anythingElse' => DataModInterface::NOT_MAPPED,
        'somethingElse' => DataModInterface::NOT_MAPPED,
    ];
}


# FeatureContext.php


use Exception;
use QuickPack\DataMod\User\User;

/**
 * Ideally you would want to separate the data step definitions from interactive/assertive step definitions.
 * This is for demonstration only.
 */
class FeatureContext
{
    /**
     * @Given I have a User
     *
     * Use the API to create a fixture user.
     */
    public function createUser()
    {
        // This will create a fixture user.
        // The name will be set to 'Wahab Qureshi'. The rest of the fields if  random users.
        for($i = 0; $i < 10; $i++) {
            // Store the ids created for these users maybe?
            $this->userIds[] = User::createFixture();
        }

        // Restore session of the user we created above.
        User::restoreSession();
    }

    /**
     * @Given I should see a User
     *
     * Use the API to retrieve the user created.
     */
    public function assertUserOnPage()
    {
        // Assumptions - we ran the following before running this command:
        // Given I have a User
        // And I have 10 Users

        // Retrieve data created, this will reference the user created by 'Given I have a User' as the session was preserved.
        $id = User::getValue('id');
        $name = User::getValue('name');
        $dateOfBirth = User::getValue('dateOfBirth');
        $gender = User::getValue('gender');

        // Assert that data is on the page.
        $this->assertSession()->assertTextOnPage($id);
        $this->assertSession()->assertTextOnPage($name);
        $this->assertSession()->assertTextOnPage($dateOfBirth);
        $this->assertSession()->assertTextOnPage($gender);
    }

    /**
     * @Given I should see (number) User(s) in the list
     *
     * Consumption of the users created above. For illustration purposes only.
     */
    public function assertUserOnPage($number)
    {
        $usersList = $this->getSession()->getPage()->find('css', '#usersListContainer li');
        $actualCount = count($usersList);

        if ($number !== $actualCount) {
            throw new Exception("Expected to have '$number' users, got '$actualCount'");
        }
    }
}




namespace QuickPack\DataMod\User;

use Genesis\SQLExtensionWrapper\BaseProvider;

class User extends BaseProvider
{
    ...

    /**
     * If you've defined multiple connections, you can specify which connection to use for each of your
     * data mods.
     *
     * @return string
     */
    public static function getConnectionName()
    {
        return 'mssql';
    }

    /**
     * Special Method: Use this method to create auxiliary data off the initial create. This is suitable
     * for creating data where the tables are fragmented.
     *
     * @param int $id The id of the created record.
     * @param array $data The data that was originally passed to create.
     *
     * @return void
     */
    public static function postCreateHook($id, array $data)
    {
        Meta::createFixture(...);
    }

    /**
     * Special Method: This method if implemented is merged with the data provided.
     * Any data provided overwrites the default data.
     * This is a good opportunity to set foreign key values using the subSelect call.
     *
     * Similar methods are available:
     * - getSelectDefaults()
     * - getUpdateDefaults()
     * - getDeleteDefaults()
     *
     * @param array $data The data passed in to the data mod.
     *
     * @return array
     */
    public static function getInsertDefaults(array $data)
    {
        return [
            'dateOfBirth' => '1989-05-10',
            'gender' => Gender::subSelect('type', ['id' => 1])
        ];
    }

    /**
     * Method uses subSelect to intelligently select the Id of the status and updates the user record.
     * This is a common case where you want your feature files to be descriptive and won't just pass in id's, use
     * descriptive names instead and infer values in the lower layers.
     *
     * @param string $status The status name (enabled/disabled).
     * @param int $userId The user to update.
     *
     * @return void
     */
    public static function updateStatusById($status, $userId)
    {
        self::update(self::getBaseTable(), [
            'status' => BaseProvider::rawSubSelect('Status', 'id', ['name' => $status])
        ], [
            'id' => $userId
        ])
    }
}




namespace App\Tests\Behaviour\DomainMod;

use App\Tests\Behaviour\DataMod;
use Genesis\SQLExtensionWrapper\Contract\DomainModInterface;

class User implements DomainModInterface
{
    public static function getDataMods()
    {
        return [
            DataMod\User::class,
            DataMod\UserExt::class,
        ];
    }
}




namespace App\Tests\Behaviour\DomainMod;

use App\Tests\Behaviour\DataMod;
use Genesis\SQLExtensionWrapper\Contract\DomainModInterface;

class User implements DomainModInterface
{
    public static function getInsertDefaults()
    {
        return [
            DataMod\User::class => [
                'age' => 31
            ],
            DataMod\UserExt::class => [
                'name' => 'Jack'
            ],
        ];
    }

    public static function getDataMods()
    {
        return [
            DataMod\User::class,
            DataMod\UserExt::class,
        ];
    }
}


// We want to create a user and have its id placed in the URL such as '/user/<id>/', so we can visit the page.

// Normally with the above data mod configuration and behat-sql-extension you need to do the following:
$routes = [
    'user' => '/user/{MySuperApplication.MyUsersNew.user_id}/'
];

// Having a data mod gives you a way to abstract any table information 
// by just referencing the data mod itself. The above can be re-written as:
$routes = [
    'user' => '/user/' . User::getKeyword('id') . '/'
];


    /**
     * @Given I am on the :arg1 page
     * @Given I visit the :arg1 page
     */
    public function iAmOnThePage($arg1)
    {
        $url = Routing::getRoute($arg1, function ($url) {
            return BaseProvider::getApi()->get('keyStore')->parseKeywordsInString($url);
        });
        $this->getMink()->getSession()->visit($url);
    }

# BaseDataMod.php


use Genesis\SQLExtensionWrapper\BaseProvider;
use Genesis\SQLExtension\Context;

/**
 * Serves as a base class for your own project, makes refactoring easier if you decide to inject your own version of 
 * the API.
 */
abstract class BaseDataMod extends BaseProvider
{
    /**
     * @var array The connection details the API expects.
     */
    public static $connectionDetails;

    /**
     * @var Context\Interfaces\APIInterface
     */
    private static $sqlApi;

    /**
     * @return Context\Interfaces\APIInterface
     */
    public static function getAPI()
    {
        if (! self::$sqlApi) {
            self::$sqlApi = new Context\API(
                new Context\DBManager(Context\DatabaseProviders\Factory(), self::$connectionDetails),
                new Context\SQLBuilder(),
                new Context\LocalKeyStore(),
                new Context\SQLHistory()
            );
        }

        return self::$sqlApi;
    }
}

class FeatureContext
{
    public function __construct()
    {
        $bridgeObject = new DoctrineBridge();
        DataModSQLContext::registerBridge($bridgeObject);
    }
}