beta / data.provider
一些数据提供者实现
1.4.6
2024-09-05 15:12 UTC
Requires
- php: >=7.2
- ext-json: *
- ext-pdo: *
- ext-simplexml: *
Requires (Dev)
- fakerphp/faker: ^1.19
- phpunit/phpunit: ^8.5
- squizlabs/php_codesniffer: ^3.6
- vimeo/psalm: ^4.20
README
该库提供统一接口以操作不同数据源:pdo, json, xml, csv...
该库实现了2个主要实体
- 提供者(DataProviderInterface)- 代表数据源接口,支持查询、过滤、排序、添加、更新和删除数据。
- 迁移者(DataMigratorInterface)- 允许在不同数据源之间交换数据。
当前实现了以下数据提供者
- PdoDataProvider - 允许通过PDO接口操作数据库,需要传递SQL查询构造器,目前实现了支持MySQL方言的构造器。
- JsonDataProvider - 允许处理json文件数据。
- XmlDataProvider - 允许处理xml文件数据。
- CsvDataProvider - 允许处理csv文件数据。
- ClosureDataProvider - 派生提供者,用于请求任意数据,但不支持保存、更新和删除操作,作为参数接收一个匿名函数,该函数应返回包含数据的关联数组。适用于生成测试数据,例如通过fzaninotto/faker库。
数据提供者使用示例
use PDO; use Data\Provider\Providers\PdoDataProvider; use Data\Provider\Providers\JsonDataProvider; use Data\Provider\Providers\XmlDataProvider; use Data\Provider\Providers\CsvDataProvider; use Data\Provider\Providers\ClosureDataProvider; use Data\Provider\SqlBuilderMySql; use Data\Provider\QueryCriteria; use Data\Provider\Interfaces\QueryCriteriaInterface; use Data\Provider\Interfaces\CompareRuleInterface; use Data\Provider\Interfaces\TransactionOperationResultInterface; use Faker\Factory; $pdo = new PDO('mysql:host=localhost;dbname=mydb;charset=UTF8', 'username', 'password'); $pdoProvider = new PdoDataProvider( $pdo, // указываем объект для подключения через интерфейс PDO 'users', // указываем таблицу с которой будем работать new SqlBuilderMysql(), // указываем конструктор SQL запросов 'id' // указываем первичный плюч ); $jsonProvider = new JsonDataProvider( $_SERVER['DOCUMENT_ROOT'].'/users.json', // указываем путь к json файлу 'id' // указываем первичный ключ ); $xmlProvider = new XmlDataProvider( $_SERVER['DOCUMENT_ROOT'].'/users.xml', // указываем путь к xml файлу 'list', // имя xml узла от которого будут читаться данные 'item', // имя xml узла элемента 'id', // указываем первичный ключ 'otheritem' // имя xml узла для перечисляемых данных (массивы) ); $csvProvider = new CsvDataProvider( $_SERVER['DOCUMENT_ROOT'].'/users.csv', // указываем путь к csv файлу 'id', // указываем первичный ключ ';', '"', '\\' ); $faker = Factory::create('ru_RU'); $fakerProvider = new ClosureDataProvider( 10, // указываем ограничение по количеству генерируемых данных по-умолчанию (можно изменить через объект QueryCriteriaInterface указав свой лимит) function (QueryCriteriaInterface $query) use ($fakerFactory) { return [ 'id' => $fakerFactory->randomNumber(), 'name' => $fakerFactory->firstName, 'email' => $fakerFactory->safeEmail ]; } ); $query = new QueryCriteria(); $query->addCriteria('id', CompareRuleInterface::IN, [1,3,5]); $query->setLimit(3); $query->setOrderBy('id', false); $pdoData = $pdoProvider->getData($query); // данные из таблицы users соотвествующие критериям выборки $jsonData = $jsonProvider->getData($query); // данные из файла users.json соотвествующие критериям выборки $xmlData = $xmlProvider->getData($query); // данные из файла users.xml соотвествующие критериям выборки $csvData = $csvProvider->getData($query); // данные из файла users.csv соотвествующие критериям выборки $fakerData = $fakerProvider->getData($query); // сгенерированные данные (в этом примере через бибилотеку fzaninotto/faker) $jsonProvider->startTransaction(); // запускаем транзакцию $dataForSave = [ 'name' => 'test', 'email' => 'user@example.com' ]; $resultAdd = $pdoProvider->save($dataForSave); // пример добавления данных $updateQueryCriteria = new QueryCriteria(); $updateQueryCriteria->addCriteria('id', CompareRuleInterface::MORE, 10); // будем обновлять только записи со значением столбца id > 10 $updateQueryCriteria->setLimit(10); // обновим не более 10 записей соотвествующих условию выше $dataForSave = [ 'name' => 'hidden', ]; $updateResult = $jsonProvider->save($dataForSave, $query); // пример обновления данных $deleteQuery = new QueryCriteria(); $deleteQuery->addCriteria('name', CompareRuleInterface::LIKE, 'test'); // будем удалять всех пользователей в имени которых есть слово test $deleteQuery->setLimit(100); // удалим не более 100 пользователей $csvProvider->remove($query); // пример удаления данных $jsonProvider->commitTransaction(); // фиксируем транзакцию if ($updateResult instanceof TransactionOperationResultInterface) { // выполнялась ли операция в транзакции if ($updateResult->isFinished()) { // проверяем стутс транзакции $updateResult->hasError(); // проверяем наличие ошибки $updateResult->getData(); // данные операции } }
不同数据源之间数据交换示例
use PDO; use Data\Provider\Providers\PdoDataProvider; use Data\Provider\Providers\ClosureDataProvider; use Data\Provider\DefaultDataMigrator; use Data\Provider\QueryCriteria; use Data\Provider\Interfaces\CompareRuleInterface; $pdo = new PDO('mysql:host=localhost;dbname=mydb;charset=UTF8', 'username', 'password'); $pdoProvider = new PdoDataProvider( $pdo, // указываем объект для подключения через интерфейс PDO 'users', // указываем таблицу с которой будем работать new SqlBuilderMysql(), // указываем конструктор SQL запросов 'id' // указываем первичный плюч ); $faker = Factory::create('ru_RU'); $fakerProvider = new ClosureDataProvider( 10, // указываем ограничение по количеству генерируемых данных по-умолчанию (можно изменить через объект QueryCriteriaInterface указав свой лимит) function (QueryCriteriaInterface $query) use ($fakerFactory) { return [ 'id' => $fakerFactory->randomNumber(), 'name' => $fakerFactory->firstName, 'email' => $fakerFactory->safeEmail ]; } ); $migrator = new DefaultDataMigrator( $fakerProvider, // источник данных $pdoProvider // приемник данных ); $query = new QueryCriteria(); $query->setLimit(20); // увеличиваем количество генерируемых данных с 10 до 20 $migrateInsertResult = $migrator->runInsert($query); // добавление сгенерированных данных в таблицу users $migrateInsertResult->getErrors(); // есть ли ошибки в процессе добавления данных в таблицу $migrateInsertResult->getErrors(); // список ошибок $migrateInsertResult->getSourceData(); // сгененрированные для записи данные $migrateInsertResult->getUnimportedDataList(); // список данных которые не удалось добавить в таблицу $migrator->runUpdate($query, function ($dataForMigrate) { // обновление данных в таблице соотвествующие критериям укзанным во втором аргументе сгенерированными данными $query = new QueryCriteria(); $query->addCriteria('id', CompareRuleInterface::EQUAL, $dataForMigrate['id']); return $query; }, true); // указываем что данные не найденые по критериям будут добавлены в таблицу как новые записи $migrator->runUpdate($query, 'id'); // обновление данных в таблице аналогично примеру выше, в данном случае во втором аргументе передается имя ключа источника, данные которого будут сравниваться с первичным ключом приемника