Skip to content

Commit

Permalink
docs: mapping, crud, queries, validation
Browse files Browse the repository at this point in the history
  • Loading branch information
roydejong committed Jun 24, 2024
1 parent 8414d5b commit 1b02532
Show file tree
Hide file tree
Showing 5 changed files with 427 additions and 1 deletion.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,17 @@ echo "Created user #{$user->id}!";

## Features

### 🗺️ [Object Mapping](./docs/ObjectMapping.md)
Define your models as pure PHP classes with typed properties. Use them like regular objects.

### 📦 [Easy CRUD](./docs/CRUD.md)
Use intuitive object-oriented CRUD (create, read, update, and delete) operations on your models.

### 🔎 [Query Builder](./docs/Queries.md)
Use the query builder to quickly build and run more complex queries with prepared statements.

### 🤝 [Relationships](./docs/Relationships.md)
Define relationships between your models and easily load them in an optimized way.
Set up relationships between your models and easily load them in an optimized way.

### [Validation](./docs/Validation.md)
Add constraints to your model properties and validate them with user-friendly error messages.
Expand Down
79 changes: 79 additions & 0 deletions docs/CRUD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# CRUD
**Once your [models are set up](./ObjectMapping.md), you can immediately use CRUD (create, update, delete) operations on them with.**

## Creating records
Initialize a model instance, set its properties, and call `save()` to insert it into the database:

```php
$car = new Car();
$car->make = "Toyota";
$car->model = "Corolla";
$car->year = 2005;
$car->save(); // INSERT INTO cars [..]
```

## Fetching by ID
Load a record by its primary key:

```php
$car = Car::find(123); // SELECT * FROM cars WHERE id = 123
```

## Updating records
Modify a model instance and call `save()` to update it in the database:

```php
$car = Car::find(123);
$car->year = 2006;
$car->save(); // UPDATE cars SET year = 2006 WHERE id = 123
```

Calling `save()` will only update the properties that have changed.

## Upserting records
Upsert allows you to update an existing record, or insert a new one if it doesn't exist:

```php
$car = new Car();
$car->make = "VW";
$car->model = "Golf";
$car->year = 2005;
$car->upsert(); // INSERT INTO cars [..] ON DUPLICATE KEY UPDATE [..]
```

Calling `upsert()` will insert or update *all* values (not just dirty ones).

## Deleting records
Call `delete()` on a model instance to remove it from the database:

```php
$car = Car::find(123);
$car->delete(); // DELETE FROM cars WHERE id = 123
```

## Querying records
Use the `query()` method to build complex queries:

```php
$matchingCars = Car::query()
->where('make = ?', 'Toyota')
->queryAllModels();
```

See the [Queries](./Queries.md) documentation for more details on query building.

## Fetch matching existing record
Use the `fetchExisting()` method to quickly fetch any model with identical values:

```php
$car = new Car();
$car->make = "Toyota";
$car->model = "Corolla";
$car->year = 2005;

if ($existingCar = $car->fetchExisting()) {
echo "Found matching existing car with ID: " . $existingCar->id;
}
```

You can even use `tryBecomeExisting()` to assume the properties and ID of an existing record if one can be found.
110 changes: 110 additions & 0 deletions docs/ObjectMapping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Object Mapping
**Define your models as pure PHP classes with typed properties, and get instant [CRUD operations](./CRUD.md).**

## Defining models
Each model is mapped to a database table.

A model itself is a pure PHP class with typed properties that extends from the `Model` base class that Instarecord provides.

```php
<?php

use SoftwarePunt\Instarecord\Model;

class MyModel extends Model // maps to "my_models" table
{
public string $someField; // maps to "some_field" column
}
```

Instarecord will treat any **public properties** as columns in the database table.

## Table and column names
Instarecord will translate `CamelCased` class and property names to `snake_case` for use in the database.

In the example above:
- `MyModel` would map to the `my_models` table (pluralized and snake_cased)
- `someField` would map to the `some_field` column (snake_cased)

### Custom table names
You can manually override the table name by adding a `TableName` attribute on the model class:

```php
<?php

use SoftwarePunt\Instarecord\Model;
use SoftwarePunt\Instarecord\Attributes\TableName;

#[TableName("custom_table_name")]
class MyModel extends Model
{
public string $someField;
}
```

## Primary keys
⚠️ Instarecord assumes (and therefore currently **requires**) that the primary key is always an auto-incrementing integer named `id`.

## Data types
The type of each property is used to determine the column type in the database. Each type is handled differently.

Each property can also be declared nullable, which Instarecord will use to determine default and accepted values.

The following types are currently supported / mapped:

### `string`
- Default/fallback type for any untyped properties.
- String properties map to varchar or text columns.
- Default value is empty string `""`.

### `DateTime`
- Serialized in the `Y-m-d H:i:s` format.
- Converted to/from the timezone specified in the `DatabaseConfig` (defaults to UTC).

### `bool`
- Stored as integer value 0 or 1.

### `int`
- Stored as an integer number without decimals.
- May be signed or unsigned; may be backed by any *int column type.

### `float`
- Stored as a decimal number.

### Enums
- Only backed enums (enums with a value type) are supported.
- When writing to the database, enums are stored as their backed enum value (column type should match).
- When reading from the database, `Enum::tryFrom()` is used. Any invalid values become `null`.

### Serialized Objects
Any object implementing `IDatabaseSerializable` can be stored as a serialized string.

This can be useful for storing as JSON, or for any other custom serialization/deserialization that can be stored as a string.

```php
<?php

use SoftwarePunt\Instarecord\Serialization\IDatabaseSerializable;

class MyCustomObject implements IDatabaseSerializable
{
public function serializeForDatabase(): string
{
return json_encode($this);
}

public static function deserializeFromDatabase(string $serialized): self
{
return json_decode($serialized, true);
}
}

class MyModel extends Model
{
public MyCustomObject $someField;
}
```

### Relationship Objects
Any other object type is treated as a relationship object. For more details, see [Relationships](./Relationships.md).

Loading

0 comments on commit 1b02532

Please sign in to comment.