Use streaming parser in schedules

This commit is contained in:
Kacper Donat 2020-01-11 13:05:32 +01:00
parent 5fb80224ce
commit f64855e454
23 changed files with 368 additions and 103 deletions

View File

@ -13,5 +13,5 @@ APP_SECRET=1bdf86cdc78fba654e4f2c309c6bbdbd
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# Configure your db driver and server_version in config/packages/doctrine.yaml
DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"
DATABASE_URL=sqlite:///%kernel.project_dir%/var/app.db
###< doctrine/doctrine-bundle ###

View File

@ -7,6 +7,7 @@
"ext-ctype": "*",
"ext-iconv": "*",
"ext-json": "*",
"cerbero/json-objects": "^1.1",
"doctrine/doctrine-cache-bundle": "^1.4",
"jms/serializer-bundle": "^3.5",
"nelmio/api-doc-bundle": "^3.5",

178
composer.lock generated
View File

@ -4,8 +4,66 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "ea09297f32ae7bb1a4392cb514b0d0b2",
"content-hash": "8efb4e4271b8598760e37b9b33d9a14f",
"packages": [
{
"name": "cerbero/json-objects",
"version": "v1.1.2",
"source": {
"type": "git",
"url": "https://github.com/cerbero90/json-objects.git",
"reference": "21eac219bb20ca80318fec88821217d7417ee09a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cerbero90/json-objects/zipball/21eac219bb20ca80318fec88821217d7417ee09a",
"reference": "21eac219bb20ca80318fec88821217d7417ee09a",
"shasum": ""
},
"require": {
"php": "~7.1",
"psr/http-message": "^1.0",
"salsify/json-streaming-parser": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.2",
"phpunit/phpunit": ">=7.0",
"squizlabs/php_codesniffer": "^3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Cerbero\\JsonObjects\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Andrea Marco Sartori",
"email": "andrea.marco.sartori@gmail.com",
"homepage": "https://github.com/cerbero90",
"role": "Developer"
}
],
"description": "Extract objects from large JSON files, endpoints or streams while saving memory.",
"homepage": "https://github.com/cerbero90/json-objects",
"keywords": [
"cerbero",
"json",
"json-objects",
"parser",
"stream"
],
"time": "2019-04-26T13:04:36+00:00"
},
{
"name": "doctrine/annotations",
"version": "v1.8.0",
@ -2964,6 +3022,56 @@
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/log",
"version": "1.1.2",
@ -3011,6 +3119,74 @@
],
"time": "2019-11-01T11:05:21+00:00"
},
{
"name": "salsify/json-streaming-parser",
"version": "v8.1.0",
"source": {
"type": "git",
"url": "https://github.com/salsify/jsonstreamingparser.git",
"reference": "0e5b5cb12611fe5376af653b360e12e8c6c6f3bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/salsify/jsonstreamingparser/zipball/0e5b5cb12611fe5376af653b360e12e8c6c6f3bd",
"reference": "0e5b5cb12611fe5376af653b360e12e8c6c6f3bd",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-mbstring": "*",
"php": "^7.1"
},
"require-dev": {
"ext-json": "*",
"satooshi/php-coveralls": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.0-dev"
}
},
"autoload": {
"psr-4": {
"JsonStreamingParser\\": "src",
"JsonStreamingParser\\Test\\": "tests"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Gonzalez",
"email": "rob@salsify.com",
"homepage": "http://salsify.com/"
},
{
"name": "Maxim Gnatenko",
"email": "mgnatenko@gmail.com"
},
{
"name": "Max Grigorian",
"email": "maxakawizard@gmail.com",
"homepage": "http://wizardcat.com/"
},
{
"name": "ThePanz",
"email": "thepanz@gmail.com"
}
],
"description": "A streaming parser for JSON in PHP.",
"homepage": "https://github.com/salsify/jsonstreamingparser",
"keywords": [
"json",
"parser",
"streaming"
],
"time": "2019-10-13T13:40:17+00:00"
},
{
"name": "sensio/framework-extra-bundle",
"version": "v5.5.3",

View File

@ -5,8 +5,8 @@ doctrine:
dbal:
driver: 'pdo_sqlite'
url: '%env(resolve:DATABASE_URL)%'
logging: false
profiling: false
logging: true
profiling: true
orm:
auto_generate_proxy_classes: '%kernel.debug%'

View File

@ -1,4 +1,4 @@
version: '3'
version: '2'
services:
nginx:
@ -11,6 +11,9 @@ services:
php:
build: docker/php
mem_limit: 2g
env_file:
- ./docker/php/.env
volumes:
- ./:/var/www:cached
- ./docker/php/log.conf:/usr/local/etc/php-fpm.d/zz-log.conf

2
docker/php/.env Normal file
View File

@ -0,0 +1,2 @@
XDEBUG_CONFIG=remote_host=172.17.0.1 remote_port=9001
PHP_IDE_CONFIG=serverName=czydojade

View File

@ -7,6 +7,8 @@ RUN docker-php-ext-install zip
RUN pecl install xdebug-2.9.0 && docker-php-ext-enable xdebug
RUN echo "xdebug.remote_enable = 1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini;
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
@ -15,4 +17,6 @@ RUN mv composer.phar /usr/local/bin/composer
RUN chmod +x /usr/local/bin/composer
RUN ln -snf /usr/share/zoneinfo/Europe/Warsaw /etc/localtime
WORKDIR /var/www
WORKDIR /var/www
EXPOSE 9001

View File

@ -7,14 +7,15 @@
</div>
<div class="departure__time">
<span class="departure__scheduled" v-if="departure.scheduled.format('HH:mm') !== departure.estimated.format('HH:mm')">
<fa :icon="['far', 'clock']" v-if="!departure.estimated" title="Czas rozkładowy, nie uwzględniający aktualnej sytuacji komunikacyjnej."/>
<span :class="[ 'departure__scheduled', departure.estimated && departure.scheduled.format('HH:mm') !== departure.estimated.format('HH:mm') && 'departure__scheduled--delayed']">
{{ departure.scheduled.format('HH:mm') }}
</span>
<span class="badge" :class="[departure.delay < 0 ? 'badge-danger' : 'badge-warning']"
v-if="departure.delay < 0 || departure.delay > 30">
{{ departure.delay|signed }}s
</span>
<span class="departure__estimated">{{ departure.estimated.format('HH:mm') }}</span>
<span class="departure__estimated" v-if="departure.estimated && departure.scheduled.format('HH:mm') !== departure.estimated.format('HH:mm')">{{ departure.estimated.format('HH:mm') }}</span>
</div>
<div class="departure__stop">
@ -28,4 +29,4 @@
<fa :icon="['fal', 'info-circle']"/>
Wybierz przystanki korzystając z wyszukiwarki poniżej, aby zobaczyć listę odjazdów.
</div>
</div>
</div>

View File

@ -24,7 +24,7 @@
width: 9rem;
text-align: right;
.departure__scheduled {
.departure__scheduled--delayed {
text-decoration: line-through;
}
}

View File

@ -5,7 +5,7 @@ import { Moment } from "moment";
export interface Departure {
display: string;
estimated: Moment;
scheduled: Moment;
scheduled?: Moment;
stop: Stop;
line: Line;
delay: number;
@ -17,4 +17,4 @@ export interface Vehicle {
id: string;
// todo: ???
}
}

View File

@ -45,7 +45,7 @@ export const departures: Module<DeparturesState, RootState> = {
const departures = await response.json() as Jsonified<Departure>[];
commit('update', departures.map(departure => {
departure.scheduled = moment.parseZone(departure.scheduled);
departure.estimated = moment.parseZone(departure.estimated);
departure.estimated = departure.estimated && moment.parseZone(departure.estimated);
return departure as Departure;
}));
@ -53,4 +53,4 @@ export const departures: Module<DeparturesState, RootState> = {
}
};
export default departures;
export default departures;

View File

@ -61,7 +61,8 @@ class DeparturesController extends Controller
*/
public function stops(DepartureRepository $departures, StopRepository $stops, Request $request)
{
$stops = $stops->getManyById($request->query->get('stop'))
$stops = $stops
->getManyById($request->query->get('stop'))
->flatMap([ $departures, 'getForStop' ])
->sortBy(function (Departure $departure) {
return $departure->getEstimated();

View File

@ -38,15 +38,14 @@ class TrackEntity implements Entity, Fillable
*
* @var LineEntity
*
* @ORM\ManyToOne(targetEntity=LineEntity::class, fetch="EAGER")
* @ORM\ManyToOne(targetEntity=LineEntity::class, fetch="EAGER", inversedBy="tracks")
*/
private $line;
/**
* Stops in track
* @var Collection
* @ORM\OneToMany(targetEntity=StopInTrack::class, fetch="EXTRA_LAZY", mappedBy="track", cascade={"persist"})
* @ORM\OrderBy({"order": "ASC"})
* @ORM\OneToMany(targetEntity=StopInTrack::class, fetch="LAZY", mappedBy="track", cascade={"persist"})
*/
private $stopsInTrack;
@ -104,4 +103,4 @@ class TrackEntity implements Entity, Fillable
{
$this->stopsInTrack = new ArrayCollection($stopsInTrack);
}
}
}

View File

@ -113,4 +113,4 @@ class TripEntity implements Entity, Fillable
{
$this->stops = new ArrayCollection(is_array($stops) ? $stops : iterator_to_array($stops));
}
}
}

View File

@ -8,6 +8,7 @@ use App\Model\Trip;
use App\Service\IdUtils;
use Carbon\Carbon;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Tests\Fixtures\Discriminator\Car;
/**
* @ORM\Entity
@ -26,7 +27,7 @@ class TripStopEntity implements Fillable
/**
* @var TripEntity
* @ORM\ManyToOne(targetEntity=TripEntity::class, fetch="EAGER")
* @ORM\ManyToOne(targetEntity=TripEntity::class, fetch="EAGER", inversedBy="stops")
* @ORM\Id
*/
private $trip;
@ -98,11 +99,11 @@ class TripStopEntity implements Fillable
public function getDeparture(): Carbon
{
return $this->departure;
return Carbon::instance($this->departure);
}
public function setDeparture(Carbon $departure): void
{
$this->departure = $departure;
}
}
}

View File

@ -3,31 +3,66 @@
namespace App\Provider\Database;
use App\Entity\StopEntity;
use App\Entity\StopInTrack;
use App\Entity\TrackEntity;
use App\Entity\TripStopEntity;
use App\Model\Departure;
use App\Model\Line;
use App\Model\Stop;
use App\Model\Vehicle;
use App\Provider\ScheduleRepository;
use Carbon\Carbon;
use Tightenco\Collect\Support\Collection;
use function Kadet\Functional\ref;
class GenericScheduleRepository extends DatabaseRepository
class GenericScheduleRepository extends DatabaseRepository implements ScheduleRepository
{
const DEFAULT_DEPARTURES_COUNT = 8;
public function getDeparturesForStop(Stop $stop, \DateTime $from, int $count = 8)
{
public function getDeparturesForStop(
Stop $stop,
\DateTime $from,
int $count = ScheduleRepository::DEFAULT_DEPARTURES_COUNT
): Collection {
$query = $this->em
->createQueryBuilder()
->select('s')
->from(TripStopEntity::class, 's')
->where('s.arrival >= :from')
->andWhere('s.stop = :stop')
->select('ts', 't')
->from(TripStopEntity::class, 'ts')
->where('ts.departure >= :from')
->andWhere('ts.stop = :stop')
->join('ts.trip', 't')
->orderBy('ts.departure', 'ASC')
->setMaxResults($count)
->getQuery()
;
->getQuery();
$schedule = collect($query->execute([
'from' => $from,
'stop' => $this->reference(StopEntity::class, $stop),
]));
return $schedule->map(ref([$this, 'convert']));
$this->em->createQueryBuilder()
->select('t', 's', 'st')
->from(TrackEntity::class, 't')
->join('t.stopsInTrack', 's')
->join('s.stop', 'st')
->where('t.id in (:tracks)')
->orderBy('s.order', 'DESC')
->getQuery()
->execute([
':tracks' => $schedule->map(function (TripStopEntity $stop) {
return $stop->getTrip()->getTrack()->getId();
})->all()
]);
return $schedule->map(function (TripStopEntity $entity) use ($stop) {
$line = $entity->getTrip()->getTrack()->getLine();
/** @var StopEntity $last */
$last = $entity->getTrip()->getTrack()->getStopsInTrack()->last()->getStop();
return Departure::createFromArray([
'scheduled' => $entity->getDeparture(),
'stop' => $stop,
'display' => $last->getName(),
'line' => $this->convert($line),
]);
});
}
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Provider;
use App\Model\Stop;
use Tightenco\Collect\Support\Collection;
interface ScheduleRepository
{
const DEFAULT_DEPARTURES_COUNT = 8;
public function getDeparturesForStop(
Stop $stop,
\DateTime $from,
int $count = ScheduleRepository::DEFAULT_DEPARTURES_COUNT
): Collection;
}

View File

@ -16,6 +16,7 @@ use App\Model\Location;
use App\Service\DataUpdater;
use App\Service\IdUtils;
use Carbon\Carbon;
use Cerbero\JsonObjects\JsonObjects;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Psr\Log\LoggerInterface;
@ -24,6 +25,7 @@ use Symfony\Component\Console\Output\ConsoleSectionOutput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Tightenco\Collect\Support\Collection;
use function Cerbero\JsonObjects\JsonObjects;
use function Kadet\Functional\ref;
class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
@ -63,6 +65,8 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
public function update(DataUpdateEvent $event)
{
$output = $event->getOutput();
$provider = ProviderEntity::createFromArray([
'name' => $this->provider->getName(),
'class' => ZtmGdanskProvider::class,
@ -76,8 +80,13 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
$this->getOperators($provider, $event)->each($save);
$this->getStops($provider, $event)->each($save);
$this->getTracks($provider, $event)->each($save);
$lines = $this->getLines($provider, $event)->each($save);
$output->write('Flushing all things into database...');
$this->em->flush();
$this->em->clear();
$output->writeln('done');
$this->updateSchedule($provider, $lines, $event);
}
@ -144,20 +153,24 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
$output->writeln(sprintf('done (%d)', count($stops)));
$this->logger->debug(sprintf("Saving %d stops tracks from ZTM Gdańsk.", count($stops)));
return collect($stops)->map(function ($stop) use ($provider) {
return StopEntity::createFromArray([
'id' => $this->ids->generate($provider, $stop['stopId']),
'name' => trim($stop['stopName'] ?? $stop['stopDesc']),
'variant' => trim($stop['zoneName'] == 'Gdańsk' ? $stop['stopCode'] : null),
'latitude' => Location::fromArray($stop['stopLat']),
'longitude' => $stop['stopLon'],
'onDemand' => (bool)$stop['onDemand'],
'provider' => $provider,
]);
});
return collect($stops)
->filter(function ($stop) {
return $stop['nonpassenger'] !== null && $stop['nonpassenger'] !== 1;
})
->map(function ($stop) use ($provider) {
return StopEntity::createFromArray([
'id' => $this->ids->generate($provider, $stop['stopId']),
'name' => trim($stop['stopName'] ?? $stop['stopDesc']),
'variant' => trim($stop['zoneName'] == 'Gdańsk' ? $stop['stopCode'] : null),
'latitude' => $stop['stopLat'],
'longitude' => $stop['stopLon'],
'onDemand' => (bool)$stop['onDemand'],
'provider' => $provider,
]);
});
}
public function getTracks(ProviderEntity $provider, DataUpdateEvent $event)
public function getTracks(ProviderEntity $provider, DataUpdateEvent $event, $stops = [])
{
ini_set('memory_limit', '2G');
@ -215,62 +228,59 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
'routeId' => $this->ids->of($line),
]));
$schedule = file_get_contents($url);
$schedule = json_decode($schedule, true)['stopTimes'];
$schedule = collect($schedule)->groupBy(function ($stop) {
return sprintf("%s-%d", $stop['busServiceName'], $stop['order']);
});
$schedule = JsonObjects::from($url, 'stopTimes.*');
$trips = new Collection();
collect($schedule)->map(function (Collection $trips, $id) use ($provider) {
$entity = TripEntity::createFromArray([
'id' => $this->ids->generate($provider, $id),
'operator' => $this->em->getReference(
OperatorEntity::class,
$this->ids->generate($provider, $trips->first()['agencyId'])
$schedule->each(function ($stop) use ($provider, &$trips) {
$id = sprintf('%s-%d', $stop['busServiceName'], $stop['order']);
$trip = $trips[$id] ?? $trips[$id] = (function () use ($stop, $id, $provider) {
$trip = TripEntity::createFromArray([
'id' => $this->ids->generate($provider, $id),
'operator' => $this->em->getReference(
OperatorEntity::class,
$this->ids->generate($provider, $stop['agencyId'])
),
'track' => $this->em->getReference(
TrackEntity::class,
$this->ids->generate($provider, sprintf('R%sT%s', $stop['routeId'], $stop['tripId']))
),
]);
$this->em->persist($trip);
return $trip;
})();
$base = Carbon::create(1899, 12, 30, 00, 00, 00);
$date = Carbon::createFromFormat('Y-m-d', $stop['date'])->setTime(00, 00, 00);
$arrival = $base->diff(Carbon::createFromTimeString($stop['arrivalTime']));
$departure = $base->diff(Carbon::createFromTimeString($stop['departureTime']));
$arrival = (clone $date)->add($arrival);
$departure = (clone $date)->add($departure);
$entity = TripStopEntity::createFromArray([
'trip' => $trip,
'stop' => $this->em->getReference(
StopEntity::class,
$this->ids->generate($provider, $stop['stopId'])
),
'track' => $this->em->getReference(
TrackEntity::class,
$this->ids->generate($provider, $trips->first()['tripId'])
),
'variant' => $trips->first(function ($trip) {
return !empty($trip['noteSymbol']);
}, ['noteSymbol' => null])['noteSymbol'],
'note' => $trips->first(function ($trip) {
return !empty($trip['noteSymbol']);
}, ['noteDescription' => null])['noteDescription'],
'order' => $stop['stopSequence'],
'arrival' => $arrival,
'departure' => $departure,
]);
$stops = $trips->map(function ($stop) use ($entity, $provider) {
$base = Carbon::create(1899, 12, 30, 00, 00, 00);
$date = Carbon::createFromFormat('Y-m-d', $stop['date'])->setTime(00, 00, 00);
$arrival = $base->diff(Carbon::createFromTimeString($stop['arrivalTime']));
$departure = $base->diff(Carbon::createFromTimeString($stop['departureTime']));
$arrival = (clone $date)->add($arrival);
$departure = (clone $date)->add($departure);
return TripStopEntity::createFromArray([
'trip' => $entity,
'stop' => $this->em->getReference(
StopEntity::class,
$this->ids->generate($provider, $stop['stopId'])
),
'order' => $stop['stopSequence'],
'arrival' => $arrival,
'departure' => $departure,
]);
});
$entity->setStops($stops);
return $entity;
})->each(ref([$this->em, 'persist']));
$entity->setTrip($trip);
$this->em->persist($entity);
});
$this->logger->debug(sprintf('Got schedule for line %s from ZTM Gdańsk', $line->getId()));
$this->em->flush();
$this->em->clear();
gc_collect_cycles();
}
public static function getSubscribedEvents()
@ -296,7 +306,7 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface
}
$progress->finish();
$progress->
$event->getOutput()->writeln("");
$event->getOutput()->writeln("done");
}
}

View File

@ -9,6 +9,7 @@ use App\Model\Vehicle;
use App\Provider\Database\GenericScheduleRepository;
use App\Provider\DepartureRepository;
use App\Provider\LineRepository;
use App\Provider\ScheduleRepository;
use App\Service\Proxy\ReferenceFactory;
use Carbon\Carbon;
use Tightenco\Collect\Support\Collection;
@ -24,13 +25,17 @@ class ZtmGdanskDepartureRepository implements DepartureRepository
/** @var ReferenceFactory */
private $reference;
/** @var ScheduleRepository */
private $schedule;
/**
* @param LineRepository $lines
*/
public function __construct(LineRepository $lines, ReferenceFactory $reference)
public function __construct(LineRepository $lines, ScheduleRepository $schedule, ReferenceFactory $reference)
{
$this->lines = $lines;
$this->reference = $reference;
$this->schedule = $schedule;
}
public function getForStop(Stop $stop): Collection

View File

@ -12,6 +12,7 @@ use App\Provider\DepartureRepository;
use App\Provider\LineRepository;
use App\Provider\MessageRepository;
use App\Provider\Provider;
use App\Provider\ScheduleRepository;
use App\Provider\StopRepository;
use App\Provider\TrackRepository;
use App\Provider\ZtmGdansk\{ZtmGdanskDepartureRepository, ZtmGdanskMessageRepository};
@ -67,7 +68,7 @@ class ZtmGdanskProvider implements Provider
$schedule = $schedule->withProvider($provider);
$this->lines = $lines;
$this->departures = new ZtmGdanskDepartureRepository($lines, $referenceFactory);
$this->departures = new ZtmGdanskDepartureRepository($lines, $schedule, $referenceFactory);
$this->stops = $stops;
$this->messages = $messages;
$this->tracks = $tracks;
@ -103,4 +104,4 @@ class ZtmGdanskProvider implements Provider
{
return $this->entity->getUpdateDate();
}
}
}

View File

@ -35,7 +35,7 @@ class DataUpdater
$connection->getConfiguration()->setSQLLogger(null);
$schema = $connection->getSchemaManager();
$path = $connection->getParams()['path'];
$path = preg_replace("~sqlite:///~si", '', $connection->getParams()['path']);
$backup = "$path.backup";
copy($path, $backup);
@ -56,4 +56,4 @@ class DataUpdater
throw $exception;
}
}
}
}

View File

@ -172,4 +172,4 @@ final class EntityConverter
return $this->reference->get($class, ['id' => $id]);
}
}
}

View File

@ -1,4 +1,7 @@
{
"cerbero/json-objects": {
"version": "v1.1.2"
},
"doctrine/annotations": {
"version": "1.0",
"recipe": {
@ -175,12 +178,18 @@
"psr/container": {
"version": "1.0.0"
},
"psr/http-message": {
"version": "1.0.1"
},
"psr/log": {
"version": "1.0.2"
},
"psr/simple-cache": {
"version": "1.0.1"
},
"salsify/json-streaming-parser": {
"version": "v8.1.0"
},
"sensio/framework-extra-bundle": {
"version": "5.2",
"recipe": {