{"id":27158942,"url":"https://github.com/activecollab/databaseobject","last_synced_at":"2025-04-08T22:39:36.605Z","repository":{"id":56940240,"uuid":"42403115","full_name":"activecollab/databaseobject","owner":"activecollab","description":"Object persistence, object pool, collection caching and more","archived":false,"fork":false,"pushed_at":"2024-11-06T20:34:47.000Z","size":718,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T13:03:28.364Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://labs.activecollab.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/activecollab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2015-09-13T16:19:53.000Z","updated_at":"2024-02-04T10:16:59.000Z","dependencies_parsed_at":"2023-09-23T16:34:11.007Z","dependency_job_id":"cc89eded-08f9-46ea-bf9f-2a475734f8ff","html_url":"https://github.com/activecollab/databaseobject","commit_stats":{"total_commits":271,"total_committers":3,"mean_commits":90.33333333333333,"dds":0.09225092250922506,"last_synced_commit":"6c2ad28eebd8252ecb0ca02c54c60d1f9e70ce4f"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activecollab%2Fdatabaseobject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activecollab%2Fdatabaseobject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activecollab%2Fdatabaseobject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/activecollab%2Fdatabaseobject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/activecollab","download_url":"https://codeload.github.com/activecollab/databaseobject/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247941718,"owners_count":21022035,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-08T22:39:34.492Z","updated_at":"2025-04-08T22:39:36.598Z","avatar_url":"https://github.com/activecollab.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DatabaseObject Library\n\n[![Build Status](https://travis-ci.org/activecollab/databaseobject.svg?branch=master)](https://travis-ci.org/activecollab/databaseobject)\n\nDatabaseObject library is a set of classes that make work with database just a bit easier. Here are the key concepts:\n\n1. Types - entities that map to a single table,\n1. Entities - type instances that map to a single row of a type table,\n1. Entity Manager - instances that provide access to custom type specific manipulation methods,\n1. Collections - a group of objects that meets the given criteria. This group is perfect for HTTP responses because collections support data tagging and tag validation (ETag and HTTP 304),\n1. Pool - manage registered types and make multi-type interaction possible,\n1. Producers - customise the way pool produces new instances,\n1. Validators - validate object properties before saving them to the database.\n\n## CRUD\n\nIf you wish to work with entire tables, use CRUD methods provided by `ConnectionInterface`:\n\n1. `ConnectionInterface::insert()` - insert one or more rows\n1. `ConnectionInterface::update()` - update a set of rows that match the given conditions, if any\n1. `ConnectionInterface::delete()` - drop a set of rows taht match the given conditions, if any\n\nWhen you need to work with individual instances, `PoolInterface` provides following handy methods:\n\n1. `PoolInterface::produce()` - create a new record based on the given parameters,\n1. `PoolInterface::modify()` - change the given object with a set of parameters,\n1. `PoolInterface::scrap()` - trash or permanently delete the given object.\n\n## Scrap\n\nRecently we added `ScrapInterface`. This interface should be implemented by models which support object trashing, instead of instant deletion. When `PoolInterface::scrap()` method is called, objects that implement `ScrapInterface` will be scrapped (marked as deleted or trashed, depending on a particular implementation), instead of being permanently deleted.\n\n## Finder\n\nTo set conditions, use `where` method:\n\n```php\n$pool-\u003efind(Writer::class)\n     -\u003ewhere('`birthday` \u003e ?', '1800-01-01')\n     -\u003eids();\n```\n\nThis method can be called multiple times, and all conditions will be joined in one block with `AND` operator:\n\n```php\n$pool-\u003efind(Writer::class)\n     -\u003ewhere('`birthday` \u003e ?', '1800-01-01')\n     -\u003ewhere('`birthday` \u003c ?', '1825-01-01')\n     -\u003eids();\n```\n\nFinder can join a table, either by table name:\n\n```php\n$pool-\u003efind(Writer::class)\n     -\u003ejoinTable('writer_groups')\n     -\u003ewhere('`writer_groups`.`group_id` = ?', $group_id)\n     -\u003eids();\n```\n\nor by related type:\n\n```php\n$pool-\u003efind(Writer::class)\n     -\u003ejoin(WriterGroup::class)\n     -\u003ewhere('`writer_groups`.`group_id` = ?', $group_id)\n     -\u003eids();\n```\n\nNote that in the second case, `WriterGroup` type needs to be registered in the pool.\n\n## DI Container\n\nPool implements `ActiveCollab\\ContainerAccess\\ContainerAccessInterface`, so you can set any container that implements `Interop\\Container\\ContainerInterface` interface, and that container will be passed on and made available in finders, producers and objects:\n\n```php\n$container = new Container([\n    'dependency' =\u003e 'it works!',\n]);\n\n$pool-\u003esetContainer($container);\n\nforeach ($pool-\u003efind(Writer::class)-\u003eall() as $writer) {\n    print $writer-\u003edependency . \"\\n\"; // Prints it works!\n}\n```\n\n## Generated Fields\n\nGenerated fields are fields that exist in tables, but they are not controlled or managed by the entity class itself. Instead, values of these models are set elsewhere:\n\n1. They are specifief as generated columns in table's definition,\n1. Trigger set the values,\n1. Values are set by external systems or processes.\n\nLibrary provides access to values of these fields, via accessors methods, but these values can't be set using setter methods:\n\n```php\n\u003c?php\n\nuse ActiveCollab\\DatabaseObject\\Entity\\Entity;\n\nclass StatsSnapshot extends Entity\n{\n    /**\n     * Generated fields that are loaded, but not managed by the entity.\n     *\n     * @var array\n     */\n    protected $generated_fields = ['is_used_on_day', 'plan_name', 'number_of_users'];\n    \n    /**\n     * Return value of is_used_on_day field.\n     *\n     * @return bool\n     */\n    public function isUsedOnDay()\n    {\n        return $this-\u003egetFieldValue('is_used_on_day');\n    }\n\n    /**\n     * Return value of is_used_on_day field.\n     *\n     * @return bool\n     * @deprecated use isUsedOnDay()\n     */\n    public function getIsUsedOnDay()\n    {\n        return $this-\u003egetFieldValue('is_used_on_day');\n    }\n\n    /**\n     * Return value of plan_name field.\n     *\n     * @return string\n     */\n    public function getPlanName()\n    {\n        return $this-\u003egetFieldValue('plan_name');\n    }\n\n    /**\n     * Return value of number_of_users field.\n     *\n     * @return int\n     */\n    public function getNumberOfUsers()\n    {\n        return $this-\u003egetFieldValue('number_of_users');\n    }\n}\n```\n\nValue casting can be set during entity configuration:\n\n```php\n\u003c?php\n\nuse ActiveCollab\\DatabaseConnection\\Record\\ValueCaster;\nuse ActiveCollab\\DatabaseConnection\\Record\\ValueCasterInterface;\nuse ActiveCollab\\DatabaseObject\\Entity\\Entity;\n\nclass StatsSnapshot extends Entity\n{\n    protected function configure(): void\n    {\n        $this-\u003esetGeneratedFieldsValueCaster(new ValueCaster([\n            'is_used_on_day' =\u003e ValueCasterInterface::CAST_BOOL,\n            'plan_name' =\u003e ValueCasterInterface::CAST_STRING,\n            'number_of_users' =\u003e ValueCasterInterface::CAST_INT,\n        ]));\n    }\n}\n```\n\nEntity class also refreshes the values of these fields on object save so fresh values are instantly available in case they are recalculated in the background (by a trigger or generated field expression).\n\n## To Do\n\n1. Caching,\n2. \u003cdel\u003eRemove deprecated `ObjectInterface` and `Object` class.\u003c/del\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Factivecollab%2Fdatabaseobject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Factivecollab%2Fdatabaseobject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Factivecollab%2Fdatabaseobject/lists"}