Skip to content

Commit 473d13e

Browse files
committed
- Added support for mysql, sqlite connections
- Added EntityManager - Fixed Database Connector for Laravel - Added facades for DatabaseManager and EntityManager - Updated readme
1 parent 5c16d0f commit 473d13e

File tree

8 files changed

+307
-33
lines changed

8 files changed

+307
-33
lines changed

README.md

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Cycle ORM integration for the Laravel Framework
2+
Cycle is a PHP DataMapper ORM and Data Modelling engine designed to safely work in classic and daemonized PHP
3+
applications (like RoadRunner). The ORM provides flexible configuration options to model datasets, a powerful query
4+
builder, and supports dynamic mapping schemas. The engine can work with plain PHP objects, support annotation
5+
declarations, and proxies via extensions.
26

3-
**!!! Important note!!!**
4-
At this moment this package work only with postgres database driver.
7+
Full information - https://cycle-orm.dev/docs
58

69
### Requirements
710
- Laravel 7.x
@@ -14,6 +17,14 @@ From the command line run
1417
composer require butschster/cycle-orm
1518
```
1619

20+
Optionally you can register the EntityManager, Transaction and/or ORM facade:
21+
```
22+
'DatabaseManager' => Butschster\Cycle\Facades\DatabaseManager::class,
23+
'Transaction' => Butschster\Cycle\Facades\Transaction::class,
24+
'ORM' => Butschster\Cycle\Facades\ORM::class,
25+
'EntityManager' => Butschster\Cycle\Facades\EntityManager::class,
26+
```
27+
1728
### Env variables
1829

1930
```
@@ -38,12 +49,26 @@ Publish the config file.
3849
php artisan vendor:publish --provider="Butschster\Cycle\Providers\LaravelServiceProvider" --tag=config
3950
```
4051

52+
#### Configure Databases
53+
The list of available connections and databases can be listed in the `config/cycle.php` - `database` section.
54+
For more information see https://cycle-orm.dev/docs/basic-connect#configure-databases
55+
56+
#### Getting Database Manager ($dbal)
57+
`DatabaseManager` registered as a singleton container
58+
59+
```
60+
$dbal = $this->app->get(\Spiral\Database\DatabaseManager::class);
61+
// Or
62+
$dbal = $this->app->get(\Spiral\Database\DatabaseProviderInterface::class);
63+
```
64+
65+
4166
**That's it!**
4267

4368
### Console commands
4469

4570
#### php artisan cycle:migrate
46-
Run cycle orm migrations from directory.
71+
Run cycle orm migrations from the directory.
4772

4873
#### php artisan cycle:refresh
4974
Refresh database schema.
@@ -59,6 +84,65 @@ By default, class locator looks for entities in app folder. You can specify loca
5984
...
6085
```
6186

87+
### Entity Manager
88+
The EntityManager is the central access point to ORM functionality. It can be used to find, persist and remove entities.
89+
90+
#### Using the EntityManager
91+
You can use the facade, container or Dependency injection to access the EntityManager methods
92+
```php
93+
EntityManager::persist($entity);
94+
95+
// Or
96+
97+
app(\Butschster\Cycle\Contracts\EntityManager::class)->persist($entity);
98+
99+
// Or
100+
101+
use Butschster\Cycle\Contracts\EntityManager;
102+
103+
class ExampleController extends Controller
104+
{
105+
protected $em;
106+
107+
public function __construct(EntityManager $em)
108+
{
109+
$this->em = $em;
110+
}
111+
}
112+
```
113+
114+
#### Finding entities
115+
Entities are objects with identity. Their identity has a conceptual meaning inside your domain. In a CMS application
116+
each article has a unique id. You can uniquely identify each article by that id.
117+
118+
```php
119+
$article = EntityManager::findByPK('App\Article', 1);
120+
$article->setTitle('Different title');
121+
122+
$article2 = EntityManager::findByPK('App\Article', 1);
123+
124+
if ($article === $article2) {
125+
echo "Yes we are the same!";
126+
}
127+
```
128+
129+
#### Persisting
130+
By passing the entity through the persist method of the EntityManager, that entity becomes MANAGED, which means that
131+
its persistence is from now on managed by an EntityManager.
132+
133+
```php
134+
$article = new Article;
135+
$article->setTitle('Let\'s learn about persisting');
136+
137+
EntityManager::persist($article);
138+
```
139+
140+
#### Deleting
141+
An entity can be deleted from persistent storage by passing it to the delete($entity) method.
142+
```php
143+
EntityManager::delete($article);
144+
```
145+
62146
### Example
63147

64148
#### User
@@ -168,34 +252,50 @@ class UserRepository extends Repository
168252
```php
169253
use Cycle\ORM\ORMInterface;
170254
use Butschster\Cycle\Facades\ORM;
255+
use Butschster\Cycle\Facades\EntityManager;
171256

172257
$user = new User();
258+
173259
$repository = app(ORMInterface::class)->getRepository($user);
174260
// or
175261
$repository = ORM::getRepository($user);
176262
// or
177263
$repository = ORM::getRepository(User::class);
178264

179265
$repository->persist($user);
266+
267+
// or
268+
269+
EntityManager::persist($user);
180270
```
181271

182272
#### Update user
183273
```php
184274
use Butschster\Cycle\Facades\ORM;
275+
use Butschster\Cycle\Facades\EntityManager;
185276

186277
$repository = ORM::getRepository(User::class);
187278
$user = $repository->findByPK('5c9e177b0a975a6eeccf5960');
188279
$user->setAuthPassword('secret');
189280

190281
$repository->persist($user);
282+
283+
// or
284+
285+
EntityManager::persist($user);
191286
```
192287

193288
#### Delete user
194289
```php
195290
use Butschster\Cycle\Facades\ORM;
291+
use Butschster\Cycle\Facades\EntityManager;
196292

197293
$repository = ORM::getRepository(User::class);
198294
$user = $repository->findByPK('5c9e177b0a975a6eeccf5960');
199295

200296
$repository->delete($user);
297+
298+
// or
299+
300+
EntityManager::delete($user);
201301
```

config/cycle.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,39 @@
1717
],
1818

1919
'connections' => [
20+
'sqlite' => [
21+
'driver' => Spiral\Database\Driver\SQLite\SQLiteDriver::class,
22+
'options' => [
23+
'connection' => sprintf(
24+
'sqlite:%s',
25+
env('DB_DATABASE', database_path('database.sqlite'))
26+
),
27+
'username' => env('DB_USERNAME', 'root'),
28+
'password' => env('DB_PASSWORD'),
29+
]
30+
],
31+
32+
'mysql' => [
33+
'driver' => Spiral\Database\Driver\MySQL\MySQLDriver::class,
34+
'options' => [
35+
'connection' => sprintf(
36+
'mysql:host=%s;port=%d;dbname=%s',
37+
env('DB_HOST', '127.0.0.1'),
38+
env('DB_PORT', 3304),
39+
env('DB_DATABASE', 'homestead')
40+
),
41+
'username' => env('DB_USERNAME', 'root'),
42+
'password' => env('DB_PASSWORD'),
43+
]
44+
],
45+
2046
'postgres' => [
2147
'driver' => Spiral\Database\Driver\Postgres\PostgresDriver::class,
2248
'options' => [
2349
'connection' => sprintf(
2450
'pgsql:host=%s;port=%d;dbname=%s;',
2551
env('DB_HOST', '127.0.0.1'),
26-
env('DB_PORT', '5432'),
52+
env('DB_PORT', 5432),
2753
env('DB_DATABASE', 'homestead')
2854
),
2955
'username' => env('DB_USERNAME', 'root'),

src/Contracts/EntityManager.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Butschster\Cycle\Contracts;
4+
5+
use Illuminate\Support\Collection;
6+
7+
interface EntityManager
8+
{
9+
/**
10+
* Find entity by PK
11+
*
12+
* @param string $entity
13+
* @param string|int $id
14+
* @return object|null
15+
*/
16+
public function findByPK(string $entity, $id);
17+
18+
/**
19+
* Find entity using given scope (where).
20+
*
21+
* @param array $scope
22+
* @return null|object
23+
*/
24+
public function findOne(string $entity, array $scope = []);
25+
26+
/**
27+
* Find multiple entities using given scope and sort options.
28+
*
29+
* @param string $entity
30+
* @param array $scope
31+
* @param array $orderBy
32+
*
33+
* @return Collection
34+
*/
35+
public function findAll(string $entity, array $scope = [], array $orderBy = []): Collection;
36+
37+
/**
38+
* @param object $entity
39+
* @param bool $cascade
40+
* @param bool $run
41+
*/
42+
public function persist(object $entity, bool $cascade = true, bool $run = true): void;
43+
44+
/**
45+
* @param object $entity
46+
* @param bool $cascade
47+
* @param bool $run
48+
*/
49+
public function delete(object $entity, bool $cascade = true, bool $run = true): void;
50+
}

src/Database/Connection.php

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,30 @@
44

55
use Closure;
66
use Cycle\ORM\ORMInterface;
7-
use Exception;
7+
use Illuminate\Database\ConnectionInterface;
88
use Illuminate\Database\DetectsConcurrencyErrors;
9-
use Illuminate\Database\PostgresConnection;
109
use Spiral\Database\Driver\DriverInterface;
10+
use Spiral\Database\Injection\Fragment;
1111
use Spiral\Database\Query\BuilderInterface;
1212
use Throwable;
1313

14-
class Connection extends PostgresConnection
14+
class Connection implements ConnectionInterface
1515
{
1616
use DetectsConcurrencyErrors;
1717

18-
protected ORMInterface $ORM;
19-
20-
protected DriverInterface $driver;
18+
private ORMInterface $ORM;
19+
private DriverInterface $driver;
20+
private ConnectionInterface $connection;
2121

2222
/**
23+
* @param ConnectionInterface $connection
2324
* @param ORMInterface $ORM
24-
* @param array $config
2525
*/
26-
public function __construct(ORMInterface $ORM, array $config)
26+
public function __construct(ConnectionInterface $connection, ORMInterface $ORM)
2727
{
2828
$this->ORM = $ORM;
2929
$this->driver = $ORM->getFactory()->database()->getDriver();
30-
$this->config = $config;
30+
$this->connection = $connection;
3131
}
3232

3333
/** @inheritDoc */
@@ -99,19 +99,19 @@ public function affectingStatement($query, $bindings = [])
9999
/** @inheritDoc */
100100
public function unprepared($query)
101101
{
102-
throw new Exception('Not implemented');
102+
return $this->driver->execute($query);
103103
}
104104

105105
/** @inheritDoc */
106106
public function prepareBindings(array $bindings)
107107
{
108-
throw new Exception('Not implemented');
108+
return $this->connection->prepareBindings($bindings);
109109
}
110110

111111
/** @inheritDoc */
112112
public function pretend(Closure $callback)
113113
{
114-
throw new Exception('Not implemented');
114+
return $this->connection->pretend($callback);
115115
}
116116

117117
/** @inheritDoc */
@@ -127,9 +127,9 @@ public function transaction(Closure $callback, $attempts = 1)
127127
$callbackResult = $callback($this);
128128
}
129129

130-
// If we catch an exception we'll rollback this transaction and try again if we
131-
// are not out of attempts. If we are out of attempts we will just throw the
132-
// exception back out and let the developer handle an uncaught exceptions.
130+
// If we catch an exception we'll rollback this transaction and try again if we
131+
// are not out of attempts. If we are out of attempts we will just throw the
132+
// exception back out and let the developer handle an uncaught exceptions.
133133
catch (Throwable $e) {
134134
$this->handleTransactionException(
135135
$e,
@@ -229,4 +229,9 @@ protected function handleCommitTransactionException(Throwable $e, $currentAttemp
229229

230230
throw $e;
231231
}
232+
233+
public function raw($value)
234+
{
235+
return new Fragment($value);
236+
}
232237
}

src/Entity/Manager.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Butschster\Cycle\Entity;
4+
5+
use Butschster\Cycle\Contracts\EntityManager;
6+
use Cycle\ORM\ORMInterface;
7+
use Illuminate\Support\Collection;
8+
9+
class Manager implements EntityManager
10+
{
11+
private ORMInterface $orm;
12+
13+
public function __construct(ORMInterface $orm)
14+
{
15+
$this->orm = $orm;
16+
}
17+
18+
public function findByPK(string $entity, $id)
19+
{
20+
return $this->orm->getRepository($entity)
21+
->findByPK($id);
22+
}
23+
24+
public function findOne(string $entity, array $scope = [])
25+
{
26+
return $this->orm->getRepository($entity)
27+
->findOne($scope);
28+
}
29+
30+
public function findAll(string $entity, array $scope = [], array $orderBy = []): Collection
31+
{
32+
return $this->orm->getRepository($entity)
33+
->findAll($scope, $orderBy);
34+
}
35+
36+
public function persist(object $entity, bool $cascade = true, bool $run = true): void
37+
{
38+
$this->orm->getRepository($entity)
39+
->persist($entity, $cascade, $run);
40+
}
41+
42+
public function delete(object $entity, bool $cascade = true, bool $run = true): void
43+
{
44+
$this->orm->getRepository($entity)
45+
->delete($entity, $cascade, $run);
46+
}
47+
}

0 commit comments

Comments
 (0)