diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index 9f64211..74cd16c 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -1,26 +1,28 @@
name: Documentation
-
on:
push:
branches: [master]
+permissions:
+ contents: write
jobs:
- publish:
+ deploy:
runs-on: ubuntu-latest
- name: 'Publish documentation'
steps:
- - name: Checkout
- uses: actions/checkout@v2
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
+ - uses: actions/checkout@v4
+ - name: Configure Git Credentials
+ run: |
+ git config user.name github-actions[bot]
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+ - uses: actions/setup-python@v5
with:
- php-version: '8.0'
- - name: Install halsey/journal
- run: composer global require halsey/journal
- - name: Generate
- run: composer global exec 'journal generate'
- - name: Push
- uses: peaceiris/actions-gh-pages@v3
+ python-version: 3.x
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
+ - uses: actions/cache@v4
with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./.tmp_journal/
+ key: mkdocs-material-${{ env.cache_id }}
+ path: .cache
+ restore-keys: |
+ mkdocs-material-
+ - run: pip install mkdocs-material
+ - run: mkdocs gh-deploy --force
diff --git a/.gitignore b/.gitignore
index 9d5cbb4..6c09361 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
/vendor
/.phpunit.result.cache
/.phpunit.cache
+/.cache
diff --git a/.journal b/.journal
deleted file mode 100644
index 233bb63..0000000
--- a/.journal
+++ /dev/null
@@ -1,74 +0,0 @@
-package('formal', 'access-layer', 'formal-php')
- ->menu(
- Entry::markdown(
- 'Getting started',
- Path::of('readme.md'),
- ),
- Entry::section(
- 'Connections',
- Entry::markdown(
- 'PDO',
- Path::of('connections/pdo.md'),
- ),
- Entry::markdown(
- 'Lazy',
- Path::of('connections/lazy.md'),
- ),
- Entry::markdown(
- 'Logger',
- Path::of('connections/logger.md'),
- ),
- Entry::markdown(
- 'Create your own',
- Path::of('connections/own.md'),
- ),
- ),
- Entry::section(
- 'Queries',
- Entry::markdown(
- 'SQL',
- Path::of('queries/sql.md'),
- ),
- Entry::markdown(
- 'Create table',
- Path::of('queries/create_table.md'),
- ),
- Entry::markdown(
- 'Drop table',
- Path::of('queries/drop_table.md'),
- ),
- Entry::markdown(
- 'Insert',
- Path::of('queries/insert.md'),
- ),
- Entry::markdown(
- 'Select',
- Path::of('queries/select.md'),
- ),
- Entry::markdown(
- 'Update',
- Path::of('queries/update.md'),
- ),
- Entry::markdown(
- 'Delete',
- Path::of('queries/delete.md'),
- ),
- Entry::markdown(
- 'Transactions',
- Path::of('queries/transactions.md'),
- ),
- ),
- );
-};
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6b5c6f1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+# This command is intended to be run on your computer
+serve-doc:
+ docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material
+
+build-doc:
+ docker run --rm -it -v ${PWD}:/docs squidfunk/mkdocs-material build
diff --git a/documentation/assets/favicon.png b/documentation/assets/favicon.png
new file mode 100644
index 0000000..348566e
Binary files /dev/null and b/documentation/assets/favicon.png differ
diff --git a/documentation/assets/fonts/MonaspaceNeon-Regular.woff b/documentation/assets/fonts/MonaspaceNeon-Regular.woff
new file mode 100644
index 0000000..ce0168b
Binary files /dev/null and b/documentation/assets/fonts/MonaspaceNeon-Regular.woff differ
diff --git a/documentation/assets/logo.svg b/documentation/assets/logo.svg
new file mode 100644
index 0000000..8526fb4
--- /dev/null
+++ b/documentation/assets/logo.svg
@@ -0,0 +1,22 @@
+
diff --git a/documentation/assets/stylesheets/extra.css b/documentation/assets/stylesheets/extra.css
new file mode 100644
index 0000000..e4aa2d4
--- /dev/null
+++ b/documentation/assets/stylesheets/extra.css
@@ -0,0 +1,113 @@
+@font-face {
+ font-family: "Monaspace Neon";
+ font-weight: normal;
+ font-style: normal;
+ src: url("../fonts/MonaspaceNeon-Regular.woff");
+}
+
+:root {
+ --md-code-font: "Monaspace Neon";
+}
+
+:root {
+ --light-md-code-hl-number-color: #f76d47;
+ --light-md-code-hl-function-color: #6384b9;
+ --light-md-code-hl-operator-color: #39adb5;
+ --light-md-code-hl-constant-color: #7c4dff;
+ --light-md-code-hl-string-color: #9fc06f;
+ --light-md-code-hl-punctuation-color: #39adb5;
+ --light-md-code-hl-keyword-color: #7c4dff;
+ --light-md-code-hl-variable-color: #80cbc4;
+ --light-md-code-hl-comment-color: #ccd7da;
+ --light-md-code-bg-color: #fafafa;
+ --light-md-code-fg-color: #ffb62c;
+ --light-md-code-hl-variable-color: #6384b9;
+ --dark-md-code-hl-number-color: #f78c6c;
+ --dark-md-code-hl-function-color: #82aaff;
+ --dark-md-code-hl-operator-color: #89ddff;
+ --dark-md-code-hl-constant-color: #c792ea;
+ --dark-md-code-hl-string-color: #c3e88d;
+ --dark-md-code-hl-punctuation-color: #89ddff;
+ --dark-md-code-hl-keyword-color: #c792ea;
+ --dark-md-code-hl-variable-color: #e8f9f9;
+ --dark-md-code-hl-comment-color: #546e7a;
+ --dark-md-code-bg-color: #263238;
+ --dark-md-code-fg-color: #ffcb6b;
+ --dark-md-code-hl-variable-color: #82aaff;
+}
+
+@media (prefers-color-scheme: light) {
+ .language-php > * {
+ --md-code-hl-number-color: var(--light-md-code-hl-number-color);
+ --md-code-hl-function-color: var(--light-md-code-hl-function-color);
+ --md-code-hl-operator-color: var(--light-md-code-hl-operator-color);
+ --md-code-hl-constant-color: var(--light-md-code-hl-constant-color);
+ --md-code-hl-string-color: var(--light-md-code-hl-string-color);
+ --md-code-hl-punctuation-color: var(--light-md-code-hl-punctuation-color);
+ --md-code-hl-keyword-color: var(--light-md-code-hl-keyword-color);
+ --md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
+ --md-code-hl-comment-color: var(--light-md-code-hl-comment-color);
+ --md-code-bg-color: var(--light-md-code-bg-color);
+ --md-code-fg-color: var(--light-md-code-fg-color);
+ }
+
+ .language-php .na {
+ --md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
+ }
+}
+
+[data-md-color-media="(prefers-color-scheme: light)"] .language-php > * {
+ --md-code-hl-number-color: var(--light-md-code-hl-number-color);
+ --md-code-hl-function-color: var(--light-md-code-hl-function-color);
+ --md-code-hl-operator-color: var(--light-md-code-hl-operator-color);
+ --md-code-hl-constant-color: var(--light-md-code-hl-constant-color);
+ --md-code-hl-string-color: var(--light-md-code-hl-string-color);
+ --md-code-hl-punctuation-color: var(--light-md-code-hl-punctuation-color);
+ --md-code-hl-keyword-color: var(--light-md-code-hl-keyword-color);
+ --md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
+ --md-code-hl-comment-color: var(--light-md-code-hl-comment-color);
+ --md-code-bg-color: var(--light-md-code-bg-color);
+ --md-code-fg-color: var(--light-md-code-fg-color);
+}
+
+[data-md-color-media="(prefers-color-scheme: light)"] .language-php .na {
+ --md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
+}
+
+@media (prefers-color-scheme: dark) {
+ .language-php > * {
+ --md-code-hl-number-color: var(--dark-md-code-hl-number-color);
+ --md-code-hl-function-color: var(--dark-md-code-hl-function-color);
+ --md-code-hl-operator-color: var(--dark-md-code-hl-operator-color);
+ --md-code-hl-constant-color: var(--dark-md-code-hl-constant-color);
+ --md-code-hl-string-color: var(--dark-md-code-hl-string-color);
+ --md-code-hl-punctuation-color: var(--dark-md-code-hl-punctuation-color);
+ --md-code-hl-keyword-color: var(--dark-md-code-hl-keyword-color);
+ --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
+ --md-code-hl-comment-color: var(--dark-md-code-hl-comment-color);
+ --md-code-bg-color: var(--dark-md-code-bg-color);
+ --md-code-fg-color: var(--dark-md-code-fg-color);
+ }
+
+ .language-php .na {
+ --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
+ }
+}
+
+[data-md-color-media="(prefers-color-scheme: dark)"] .language-php > * {
+ --md-code-hl-number-color: var(--dark-md-code-hl-number-color);
+ --md-code-hl-function-color: var(--dark-md-code-hl-function-color);
+ --md-code-hl-operator-color: var(--dark-md-code-hl-operator-color);
+ --md-code-hl-constant-color: var(--dark-md-code-hl-constant-color);
+ --md-code-hl-string-color: var(--dark-md-code-hl-string-color);
+ --md-code-hl-punctuation-color: var(--dark-md-code-hl-punctuation-color);
+ --md-code-hl-keyword-color: var(--dark-md-code-hl-keyword-color);
+ --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
+ --md-code-hl-comment-color: var(--dark-md-code-hl-comment-color);
+ --md-code-bg-color: var(--dark-md-code-bg-color);
+ --md-code-fg-color: var(--dark-md-code-fg-color);
+}
+
+[data-md-color-media="(prefers-color-scheme: dark)"] .language-php .na {
+ --md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
+}
diff --git a/documentation/connections/lazy.md b/documentation/connections/lazy.md
index 9bf6df3..c03ec65 100644
--- a/documentation/connections/lazy.md
+++ b/documentation/connections/lazy.md
@@ -11,7 +11,11 @@ use Formal\AccessLayer\{
};
use Innmind\Url\Url;
-$connection = new Lazy(static fn() => PDO::of(Url::of('mysql://user:pwd@127.0.0.1:3306/database_name')));
+$connection = new Lazy(
+ static fn() => PDO::of(
+ Url::of('mysql://user:pwd@127.0.0.1:3306/database_name'),
+ ),
+);
```
By passing a callable to the constructor allows you to use [whatever implementation](own.md) of a `Connection` you wish to lazy load.
diff --git a/documentation/connections/logger.md b/documentation/connections/logger.md
index 40ca3e1..38f5825 100644
--- a/documentation/connections/logger.md
+++ b/documentation/connections/logger.md
@@ -15,8 +15,8 @@ $connection = Logger::psr(
);
```
-> [!NOTE]
-> it doesn't log any information about the returned rows to prevent _unwrapping_ the deferred `Sequence` returned by [`PDO`](pdo.md).
+!!! note ""
+ It doesn't log any information about the returned rows to prevent _unwrapping_ the deferred `Sequence` returned by [`PDO`](pdo.md).
-> [!IMPORTANT]
-> it won't log any errors for lazy queries since the query is not executed until the first call on the sequence.
+!!! warning ""
+ It won't log any errors for lazy queries since the query is not executed until the first call on the sequence.
diff --git a/documentation/connections/own.md b/documentation/connections/own.md
index 8f92b01..4b4adbd 100644
--- a/documentation/connections/own.md
+++ b/documentation/connections/own.md
@@ -40,63 +40,30 @@ final class Sentry implements Connection
An important part of extending the behaviour of the connection with your own logic is to not change the current behaviour that other code may rely upon. This library helps you make sure you don't break these behaviours by providing you properties.
-Below is an example of a PHPUnit test case that you can extend to add your specific test cases:
+Below is an example of running properties via [BlackBox](https://innmind.github.io/BlackBox/):
```php
-use PHPUnit\Framework\TestCase;
-use Innmind\BlackBox\PHPUnit\BlackBox;
-use Properties\Formal\AccessLayer\Connection;
-
-class SentryTest extends TestCase
-{
- use BlackBox;
-
- public function setUp(): void
- {
- Connection::seed($this->connection());
- }
-
- // you can add here test cases like in any other PHPUnit class
-
- /**
- * @dataProvider properties
- */
- public function testHoldProperty($property)
- {
- $this
- ->forAll($property)
- ->then(function($property) {
- $connection = $this->connection();
-
- if (!$property->applicableTo($connection)) {
- $this->markTestSkipped();
- }
-
- $property->ensureHeldBy($connection);
- });
- }
-
- public function testHoldProperties()
- {
- $this
- ->forAll(Connection::properties())
- ->disableShrinking()
- ->then(function($properties) {
- $properties->ensureHeldBy($this->connection());
- });
- }
-
- public function properties(): iterable
- {
- foreach (Connection::list() as $property) {
- yield [$property];
- }
- }
-
- private function connection(): PDO
- {
- return new Sentry(/* add the arguments of your implementation here */);
- }
+use Innmind\BlackBox\Set;
+use Properties\Formal\AccessLayer\Connection as Properties;
+
+$sentry = new Sentry(/* add the arguments of your implementation here */);
+$connection = Set\Call::of(static function() use ($sentry) {
+ Properties::seed($sentry);
+
+ return $sentry;
+});
+
+yield properties(
+ 'Sentry properties',
+ Properties::any(),
+ $connection,
+);
+
+foreach (Properties::list() as $property) {
+ yield property(
+ $property,
+ $connection,
+ )->named('Sentry');
}
```
diff --git a/documentation/connections/pdo.md b/documentation/connections/pdo.md
index bee256b..7a908e7 100644
--- a/documentation/connections/pdo.md
+++ b/documentation/connections/pdo.md
@@ -13,5 +13,5 @@ $connection = PDO::of(Url::of('mysql://user:pwd@127.0.0.1:3306/database_name?cha
When executing a [query](../queries/sql.md) through this connection it will return a [deferred `Sequence`](https://innmind.github.io/Immutable/SEQUENCE.html#defer) of rows. This means that the rows returned from the database are only loaded once you iterate over the sequence. (Queries with the named constructor `::onDemand()` will return a lazy `Sequence`).
-> [!IMPORTANT]
-> as soon as you instanciate the class it will open a connection to the database, if you want to open it upon first query take a look at the [`Lazy` connection](lazy.md).
+!!! note ""
+ As soon as you instanciate the class it will open a connection to the database, if you want to open it upon first query take a look at the [`Lazy` connection](lazy.md).
diff --git a/documentation/readme.md b/documentation/index.md
similarity index 50%
rename from documentation/readme.md
rename to documentation/index.md
index c342998..067064c 100644
--- a/documentation/readme.md
+++ b/documentation/index.md
@@ -1,10 +1,17 @@
+---
+hide:
+ - navigation
+ - toc
+---
+
# Getting started
This library is designed to eliminate state wherever possible when dealing with a database connection.
-The result is an api can consist of only one method on the connection (`__invoke`) and one kind of argument (`Query`). Both can easily be extended through composition.
+The result is an api that consist of only one method on the connection (`__invoke`) and one kind of argument (`Query`). Both can easily be extended through composition.
-**Important**: you must use [`vimeo/psalm`](https://packagist.org/packages/vimeo/psalm) to make sure you use this library correctly.
+!!! note ""
+ You must use [`vimeo/psalm`](https://packagist.org/packages/vimeo/psalm) to make sure you use this library correctly.
## Installation
@@ -16,7 +23,6 @@ composer require formal/access-layer
```php
use Formal\AccessLayer\{
- Connection\Lazy,
Connection\PDO,
Query\SQL,
Row,
@@ -24,7 +30,7 @@ use Formal\AccessLayer\{
use Innmind\Url\Url;
use Innmind\Immutable\Sequence;
-$connection = new Lazy(static fn() => PDO::of(Url::of('mysql://user:pwd@127.0.0.1:3306/database_name')));
+$connection = PDO::of(Url::of('mysql://user:pwd@127.0.0.1:3306/database_name'));
$rows = $connection(SQL::of('SELECT * FROM `some_table`'));
$rows; // instanceof Sequence
diff --git a/documentation/queries/create_table.md b/documentation/queries/create_table.md
index b67c0e8..e1f868a 100644
--- a/documentation/queries/create_table.md
+++ b/documentation/queries/create_table.md
@@ -84,5 +84,5 @@ $create = $create->foreignKey(
$connection($create);
```
-> [!NOTE]
-> this will name the foreign key `FK_user_id` so it's easier to reference it afterwards.
+!!! note ""
+ This will name the foreign key `FK_user_id` so it's easier to reference it afterwards.
diff --git a/documentation/queries/delete.md b/documentation/queries/delete.md
index 495be32..544f405 100644
--- a/documentation/queries/delete.md
+++ b/documentation/queries/delete.md
@@ -60,5 +60,5 @@ $delete = Delete::from(new Name('users'))->where(
$connection($delete);
```
-> [!NOTE]
-> the property name can include the name of the table to match by using the format `'{table}.{column}'`.
+!!! note ""
+ The property name can include the name of the table to match by using the format `'{table}.{column}'`.
diff --git a/documentation/queries/select.md b/documentation/queries/select.md
index 29ae381..c8c3787 100644
--- a/documentation/queries/select.md
+++ b/documentation/queries/select.md
@@ -12,8 +12,8 @@ $users = $connection($select);
This will return all the content of the `users` table.
-> [!NOTE]
-> if you replace the constructor `::from()` by `::onDemand()` it will run your query lazily by returning a lazy `Sequence`, meaning it won't keep the results in memory allowing you to handle very large results.
+!!! note ""
+ If you replace the constructor `::from()` by `::onDemand()` it will run your query lazily by returning a lazy `Sequence`, meaning it won't keep the results in memory allowing you to handle very large results.
## Specifying columns to return
@@ -80,5 +80,7 @@ $select = Select::from(new Name('users'))->where(
$users = $connection($select);
```
-> [!NOTE]
-> the property name can include the name of the table to match by using the format `'{table}.{column}'`. The value of the specification can also be a query (this will translated to a sub query).
+!!! note ""
+ The property name can include the name of the table to match by using the format `'{table}.{column}'`.
+
+ The value of the specification can also be a query (this will translated to a sub query).
diff --git a/documentation/queries/sql.md b/documentation/queries/sql.md
index 0543b6d..9990efb 100644
--- a/documentation/queries/sql.md
+++ b/documentation/queries/sql.md
@@ -18,15 +18,15 @@ $tables->foreach(function(Row $row): void {
});
```
-> [!NOTE]
-> if you replace the constructor `::of()` by `::onDemand()` it will run your query lazily by returning a lazy `Sequence`, meaning it won't keep the results in memory allowing you to handle very large results. This is particularly useful for `SELECT` queries.
+!!! note ""
+ If you replace the constructor `::of()` by `::onDemand()` it will run your query lazily by returning a lazy `Sequence`, meaning it won't keep the results in memory allowing you to handle very large results. This is particularly useful for `SELECT` queries.
## Parameters
For some queries you will need to specify parameters to provide values, you can bind them either by specifying their name or by an index
-> [!IMPORTANT]
-> do not copy the values directly in the sql query as you'll be vulnerable to sql injection.
+!!! warning ""
+ Do not copy the values directly in the sql query as you'll be vulnerable to sql injection.
### Bound by name
@@ -54,5 +54,5 @@ $insert = $insert
$connection($insert);
```
-> [!NOTE]
-> traditionally the index value rely on the user (you) to be specified (see [`PDOStatement::bindValue`](https://www.php.net/manual/en/pdostatement.bindvalue.php)), but this increase the probability for you to make an error. This problem is resolved here as the order in which the parameters are provided is always respected, this allows the connection to correctly provide the index to `\PDO`.
+!!! note ""
+ Traditionally the index value rely on the user (you) to be specified (see [`PDOStatement::bindValue`](https://www.php.net/manual/en/pdostatement.bindvalue.php)), but this increase the probability for you to make an error. This problem is resolved here as the order in which the parameters are provided is always respected, this allows the connection to correctly provide the index to `\PDO`.
diff --git a/documentation/queries/update.md b/documentation/queries/update.md
index a812437..47cce9f 100644
--- a/documentation/queries/update.md
+++ b/documentation/queries/update.md
@@ -73,5 +73,5 @@ $update = $update->where(
$connection($update);
```
-> [!NOTE]
-> the property name can include the name of the table to match by using the format `'{table}.{column}'`.
+!!! note ""
+ The property name can include the name of the table to match by using the format `'{table}.{column}'`.
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..8d4ce8d
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,105 @@
+site_name: formal/access-layer
+repo_name: formal/access-layer
+docs_dir: documentation/
+
+nav:
+ - Home: index.md
+ - Connections:
+ - PDO: connections/pdo.md
+ - Lazy: connections/lazy.md
+ - Logger: connections/logger.md
+ - Create your own: connections/own.md
+ - Queries:
+ - SQL: queries/sql.md
+ - Create table: queries/create_table.md
+ - Drop table: queries/drop_table.md
+ - Insert: queries/insert.md
+ - Select: queries/select.md
+ - Update: queries/update.md
+ - Delete: queries/delete.md
+ - Transactions: queries/transactions.md
+
+theme:
+ name: material
+ logo: assets/logo.svg
+ favicon: assets/favicon.png
+ font: false
+ features:
+ - content.code.copy
+ - content.code.annotate
+ - navigation.tracking
+ - navigation.tabs
+ - navigation.tabs.sticky
+ - navigation.sections
+ - navigation.expand
+ - navigation.indexes
+ - navigation.top
+ - navigation.footer
+ - search.suggest
+ - search.highlight
+ - content.action.edit
+ palette:
+ # Palette toggle for automatic mode
+ - media: "(prefers-color-scheme)"
+ toggle:
+ icon: material/brightness-auto
+ name: Switch to light mode
+ primary: blue
+ accent: deep orange
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ toggle:
+ icon: material/brightness-7
+ name: Switch to dark mode
+ primary: blue
+ accent: deep orange
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ toggle:
+ icon: material/brightness-4
+ name: Switch to system preference
+ primary: blue
+ accent: deep orange
+
+markdown_extensions:
+ - pymdownx.highlight:
+ anchor_linenums: true
+ line_spans: __span
+ pygments_lang_class: true
+ extend_pygments_lang:
+ - name: php
+ lang: php
+ options:
+ startinline: true
+ - pymdownx.inlinehilite
+ - pymdownx.snippets
+ - attr_list
+ - md_in_html
+ - pymdownx.superfences
+ - abbr
+ - admonition
+ - pymdownx.details:
+ - pymdownx.tabbed:
+ alternate_style: true
+ - toc:
+ permalink: true
+ - footnotes
+ - pymdownx.emoji:
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
+
+extra_css:
+ - assets/stylesheets/extra.css
+
+plugins:
+ - search
+ - privacy
+
+extra:
+ social:
+ - icon: fontawesome/brands/github
+ link: https://github.com/formal-php
+ - icon: fontawesome/brands/x-twitter
+ link: https://twitter.com/Baptouuuu