Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

Commit

Permalink
added migration Blueprint methods and updated readme
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkingshott committed Jan 19, 2022
1 parent 05de471 commit 83fdbfd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,39 +70,42 @@ Since this is a little cumbersome, the package also registers a global `snowflak
snowflake(); // (string) "5585066784854016"
```

> **IMPORTANT**: The initial release converted the Snowflake to an integer. This has been rolled back to prevent integer overflows in some languages.
## Databases

### Eloquent models
If you want to use Snowflakes in your database e.g. for primary and foreign keys, then you'll need to perform a couple of steps.

If you want to use a Snowflake as the primary key for an Eloquent model, then you'll need to perform a couple of steps.

First, modify the model's migration so that it no longer uses auto-incrementing integers e.g.
First, modify your migrations so that they use the Snowflake migration methods e.g.

```php
// Before
$table->id();
$table->foreignId('user_id');
$table->foreignIdFor(User::class);

// After
$table->unsignedBigInteger('id')->primary();
$table->snowflake()->primary();
$table->foreignSnowflake('user_id');
$table->foreignSnowflakeFor(User::class);
```

Here's an example:

```php
class CreateUsersTable extends Migration
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('users', function(Blueprint $table) {
$table->unsignedBigInteger('id')->primary();
$table->string('name', 100);
Schema::create('posts', function(Blueprint $table) {
$table->snowflake()->primary();
$table->foreignSnowflake('user_id')->constrained()->cascadeOnDelete();
$table->string('title', 100);
$table->timestamps();
});
}
}
```

Finally, add the package's `Snowflakes` trait to the model:
Next, if you're using Eloquent, add the package's `Snowflakes` trait to your Eloquent models:

```php
<?php
Expand All @@ -111,15 +114,13 @@ namespace App\Models;

use Snowflake\Snowflakes;

class User extends Model
class Post extends Model
{
use Snowflakes;
}
```

#### Optional casting

The package also includes a custom `SnowflakeCast` that will automatically handle conversion from `string` to `integer` and vice-versa when storing or fetching a Snowflake from the database. If you wish, you may use this cast for any model attribute that will contain a Snowflake e.g.
Finally, configure the model's `$casts` array to use the package's `SnowflakeCast` for all Snowflake attributes. This cast automatically handles conversion from `string` to `integer` and vice-versa when storing or fetching a Snowflake from the database. It also ensures that languages which do not support 64-bit integers (such as JavaScript), will not truncate the Snowflake.

```php
<?php
Expand Down
4 changes: 2 additions & 2 deletions resources/version.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace Snowflake;

use Godruoyi\Snowflake\Snowflake;
use Illuminate\Database\Schema\Blueprint;
use Godruoyi\Snowflake\RandomSequenceResolver;
use Illuminate\Support\ServiceProvider as Provider;
use Illuminate\Database\Schema\ForeignIdColumnDefinition;

class ServiceProvider extends Provider
{
Expand All @@ -14,6 +16,8 @@ class ServiceProvider extends Provider
*/
public function boot() : void
{
$this->macros();

$this->publishes([__DIR__ . '/../config/snowflake.php' => config_path('snowflake.php')]);
}

Expand All @@ -28,6 +32,30 @@ public function register() : void
$this->app->singleton('snowflake', fn() => $this->singleton());
}

/**
* Register any custom macros.
*
*/
protected function macros() : void
{
Blueprint::macro('snowflake', function($column = 'id') {
return $this->unsignedBigInteger($column);
});

Blueprint::macro('foreignSnowflake', function($column) {
return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
'type' => 'bigInteger',
'name' => $column,
'autoIncrement' => false,
'unsigned' => true,
]));
});

Blueprint::macro('foreignSnowflakeFor', function($model, $column = null) {
return $this->foreignSnowflake($column ?: (new $model())->getForeignKey());
});
}

/**
* Register the Snowflake singleton service.
*
Expand Down

0 comments on commit 83fdbfd

Please sign in to comment.