Skip to content

Commit 90ea5b3

Browse files
committed
Improve DSN handling + Url Parsing
1 parent 89f3cd0 commit 90ea5b3

5 files changed

+67
-23
lines changed

README.md

+15-4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ You need to add the connection type to the database config:
4848
]
4949
```
5050

51+
You can also use URLs.
52+
53+
```dotenv
54+
DATABASE_URL=cockroachdb://<username>:<password>@<host>:<port>/<database>?sslmode=verify-full
55+
```
56+
5157
## Usage
5258

5359
To enable set `DB_CONNECTION=crdb` in your .env.
@@ -72,10 +78,9 @@ At current if you try to create a Fulltext index using the Schema builder or try
7278
method of the Query builder a `YlsIdeas\CockroachDb\Exceptions\FeatureNotSupportedException` exception will be thrown.
7379

7480
### Serverless Support
75-
Cockroach Serverless requires you to add an `options` parameter to the connection string.
76-
Laravel doesn't provide this out of the box, so, it's being implemented as an extra `cluster` parameter in the database config. Just pass the cluster identification from CockroachDB Serverless.
77-
78-
Sample config snippet:
81+
Cockroach Serverless requires you to provide a cluster with connection.
82+
Laravel doesn't provide this out of the box, so, it's being implemented as an extra `cluster` parameter in the
83+
database config. Just pass the cluster identification from CockroachDB Serverless.
7984

8085
```php
8186
'crdb' => [
@@ -95,6 +100,12 @@ Sample config snippet:
95100
]
96101
```
97102

103+
You may also use a URL in the following format.
104+
105+
```dotenv
106+
DATABASE_URL=cockroachdb://<username>:<password>@<host>:<port>/<database>?sslmode=verify-full&cluster=<cluster>
107+
```
108+
98109
## Testing
99110

100111
The tests try to closely follow the same functionality of the grammar provided by Laravel

src/CockroachDbConnector.php

+6-12
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,15 @@
88
class CockroachDbConnector extends PostgresConnector implements ConnectorInterface
99
{
1010
/**
11-
* Usually the normal PostgresConnector would suffice for Cockroach,
12-
* but Cockroach Serverless Clusters need an extra parameter `options`.
11+
* When using CockroachDB serverless it's possible to apply a namespace to the name of the database
12+
* which then allows for the service to recognise which cluster is being used.
1313
*/
14-
protected function getDsn(array $config)
14+
protected function getDsn(array $config): string
1515
{
16-
return $this->addClusterOptions(parent::getDsn($config), $config);
17-
}
18-
19-
protected function addClusterOptions(string $dsn, array $config)
20-
{
21-
if (isset($config['cluster']) && ! empty($config['cluster'])) {
22-
$clusterNameEscaped = addslashes($config['cluster']);
23-
$dsn .= ";options='--cluster={$clusterNameEscaped}'";
16+
if (($config['cluster'] ?? false) && $config['cluster'] != '') {
17+
$config['database'] = implode('.', [$config['cluster'], $config['database']]);
2418
}
2519

26-
return $dsn;
20+
return parent::getDsn($config);
2721
}
2822
}

src/CockroachDbServiceProvider.php

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,25 @@
33
namespace YlsIdeas\CockroachDb;
44

55
use Illuminate\Database\Connection;
6+
use Illuminate\Database\DatabaseManager;
7+
use Illuminate\Support\ConfigurationUrlParser;
68
use Illuminate\Support\ServiceProvider;
79

810
class CockroachDbServiceProvider extends ServiceProvider
911
{
1012
public function register()
1113
{
12-
Connection::resolverFor('crdb', function ($connection, $database, $prefix, $config) {
13-
$connector = new CockroachDbConnector();
14-
$connection = $connector->connect($config);
14+
$this->app->extend(DatabaseManager::class, function (DatabaseManager $manager) {
15+
ConfigurationUrlParser::addDriverAlias('cockroachdb', 'crdb');
1516

16-
return new CockroachDbConnection($connection, $database, $prefix, $config);
17+
Connection::resolverFor('crdb', function ($connection, $database, $prefix, $config) {
18+
$connector = new CockroachDbConnector();
19+
$connection = $connector->connect($config);
20+
21+
return new CockroachDbConnection($connection, $database, $prefix, $config);
22+
});
23+
24+
return $manager;
1725
});
1826
}
1927
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace YlsIdeas\CockroachDb\Tests\Database;
4+
5+
use Illuminate\Support\ConfigurationUrlParser;
6+
use PHPUnit\Framework\TestCase;
7+
8+
class ConfigurationUrlParserTest extends TestCase
9+
{
10+
public function test_configuration_url_parser_can_parse_cockroach_db_urls()
11+
{
12+
ConfigurationUrlParser::addDriverAlias('cockroachdb', 'crdb');
13+
14+
$parser = new ConfigurationUrlParser();
15+
16+
$config = $parser->parseConfiguration([
17+
'url' => 'cockroachdb://username:[email protected]:26257/defaultdb?sslmode=verify-full&cluster=my-cluster-123',
18+
]);
19+
20+
$this->assertSame([
21+
'driver' => 'crdb',
22+
'database' => 'defaultdb',
23+
'host' => 'hostname.example.com',
24+
'port' => 26257,
25+
'username' => 'username',
26+
'password' => 'password',
27+
'sslmode' => 'verify-full',
28+
'cluster' => 'my-cluster-123',
29+
], $config);
30+
}
31+
}

tests/Database/DatabaseCockroachDbConnectorTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function test_dsn_params_with_cluster()
2020
],
2121
);
2222

23-
$this->assertStringContainsString("options='--cluster=cluster-1234'", $dsnConfig);
23+
$this->assertStringContainsString("dbname='cluster-1234.defaultdb'", $dsnConfig);
2424
}
2525

2626
public function test_dsn_params_without_cluster()
@@ -36,13 +36,13 @@ public function test_dsn_params_without_cluster()
3636
],
3737
);
3838

39-
$this->assertStringNotContainsString("options=", $dsnConfig);
39+
$this->assertStringContainsString("dbname='defaultdb'", $dsnConfig);
4040
}
4141

4242
protected function getConnector()
4343
{
4444
return new class () extends CockroachDbConnector {
45-
public function exposeGetDsnMethod(array $config)
45+
public function exposeGetDsnMethod(array $config): string
4646
{
4747
return $this->getDsn($config);
4848
}

0 commit comments

Comments
 (0)