Skip to content

v0.2.0

Latest
Compare
Choose a tag to compare
@osmianski osmianski released this 18 Feb 09:14
· 127 commits to v0.2 since this release

Getting Started Is So Much Easier!

The main idea of v0.2 is that data classes should work without any attributes. Actually, you can even start without any properties!

It's enough to extend the Record class, generate a database table for the class using osm migrate:schema command, and you are good to go:

class Product extends Record {
}

Immediately, you'll be able to manage products visually in the admin area, integrate them with other applications using the HTTP API, or implement some internal custom logic using the query(Product::class) syntax.

Of course, you can add your own custom properties, create explicit table columns for them, compute their value using formulas, specify UI control, and many other things. Properties can be scalars, objects, arrays, or references to other records.

For more details, read the blog post.

Standard Properties

Classes inherit two properties from the Record class:

  • id - Unique auto-incremented object ID. It's used for creating relationships between objects, and for object selection in a grid.
  • title - Object title. It's used for in various places of the admin area, for example, while displaying the object in dropdown option list, or in the page title of an edit form.

Formula Syntax

The query syntax introduces formulas - SQL-like expressions that you can use in SELECT, WHERE, ORDER BY (and later GROUP BY) clauses:

$products = query(Product::class)
    ->where("id IN (1, 2, 3)")
    ->where("title LIKE '%dress%'")
    ->get('id', 'title');

You may ask why inventing the new syntax if SQL is already good at what it does. And it's a great question. The main reason for introducing formulas lies in the near future.

You'll be able to specify how a property is computed from other properties of its object, and from the properties of the related objects. For example, consider a hierarchical category object tree where child categories "inherit" their values from the parent category:

/**
 * @property ?Category $parent #[Explicit]
 * @property ?int $level #[Computed("(parent.level ?? -1) + 1")]
 * @property ?string $id_path #[
 *      Computed("(parent.id_path IS NOT NULL ? parent.id_path + '/' : '') + id"),
 * ]
 */
class Category extends Record {
}     

And raw SQL syntax is not a good fit for this use case, mainly because there is no good way to implicitly join related tables for expressions like parent.level, or parent.parent.level, and to integrate them into more complex expressions like (parent.level ?? -1) + 1".

Syntactic Sugar

There is also some syntax sugar in formula queries compared to SQL:

  1. All constants in a formula are converted to SQL bindings. For example, id IN (1, 2, 3) formula is converted into id IN (?, ?, ?) raw SQL.
  2. Instead of COALESCE(property1, property2, property3), write property1 ?? property2 ?? property3.
  3. Instead of IF(id = 1, title, status), write id = 1 ? title : status.

SQL Compatibility

Other formula syntax will be as close to standard SQL as possible, so you don't have to learn a new language.

New Architecture

In v0.1, there were over 10 modules, each responsible for a single concept. It's been a nice try, but in reality, these concepts were not as independent, and adding new features faced increasing resistance caused by unnecessary complexity.

In v0.2, the whole architecture is a lot more simplified:

New Architecture

As you can see, there are only three modules left:

  • Schema - table/class/property definitions
  • Queries - well, for querying data
  • Ui - for managing data visually, and through the API

Check more diagrams for a detailed look.

Roadmap

As I'm heading to some minimum Osm Admin user interface - one property, one data type, one UI control type - a lot of things are left unfinished.

At some point, they will! In order to keep track of them, they are listed in the product roadmap.

Related Releases