diff --git a/README.md b/README.md index decc4f2..d68b03d 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,6 @@ Please note that the following are not required, but are strongly recommended fo ## Unsupported features - STRUCT data types -- Inserting/Updating JSON data types ## Limitations @@ -235,6 +234,18 @@ When fetching rows, the library coverts the following column types Note that if you execute a query without QueryBuilder, it will not have these conversions. +### JSON Type + +In order to use JSON columns, use the provided Cast on your model as below + +```php +use Colopl\Spanner\Casts\SpannerJson; + +protected $casts = [ + 'json_column_name' => SpannerJson::class, +]; +``` + ### Partitioned DML You can run partitioned DML as below. diff --git a/src/Casts/SpannerJson.php b/src/Casts/SpannerJson.php new file mode 100644 index 0000000..a88ccfe --- /dev/null +++ b/src/Casts/SpannerJson.php @@ -0,0 +1,54 @@ + + * */ +class SpannerJson implements CastsAttributes +{ + public function get(Model $model, string $key, mixed $value, array $attributes) + { + if($value === null) { + return null; + } + + if($value instanceof SpannerJsonType) { + $value = (string) $value; + } + + if(!is_string($value)) { + throw new \InvalidArgumentException('The given value must be a string, SpannerJsonType or null'); + } + + return json_decode($value, true); + } + + public function set(Model $model, string $key, mixed $value, array $attributes) + { + if ( + !is_array($value) && + !$value instanceof \JsonSerializable && + $value !== null && + !is_string($value) + ) { + throw new \InvalidArgumentException('The given value must be an array, JsonSerializable, string or null.'); + } + + return [$key => new SpannerJsonType($value)]; + } +} + + +class SpannerJsonType extends PgJsonb +{ + public function typeAnnotation(): int + { + return TypeAnnotationCode::TYPE_ANNOTATION_CODE_UNSPECIFIED; + } +}