Skip to content

Releases: BJNSTNKVC/js-db

2.4.0

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 27 Sep 20:24

Added

  • Columns can be changed inside Schema.table with change(), as in table.string('nickname').nullable().change(). The new declaration replaces the old one where it stands, so a modifier left out is removed, including an index or unique index over that column alone.
  • A change may toggle nullable, add, change or remove a default, change the values an enum accepts, and add or remove index() and unique().
  • Existing rows are checked in the same migration. A column becoming required gives its default to rows without a value, and fails when it has no default. An enum dropping a value fails while rows still hold it. A new default fills rows missing the column. A unique index fails over repeated values. Any failure throws SchemaException naming the table, the column and the number of rows, and rolls the whole migration back.
  • Changing the key path, the type of a column or the scale of a decimal is refused with SchemaException.

Changed

  • Adding a unique index with table.unique() inside Schema.table over values that already repeat now throws SchemaException naming the columns, instead of IndexedDB's ConstraintError.

2.3.0

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 27 Sep 16:06

Added

  • Query inside json() columns with -> paths, as in where('settings->theme', 'dark'). A path works in every constraint and in orderBy, including table-qualified paths in joined queries. A missing path reads as null.
  • whereJsonContains, whereJsonDoesntContain and whereJsonLength, with or forms: orWhereJsonContains, orWhereJsonDoesntContain and orWhereJsonLength.
  • select, pluck and value read JSON paths. An unaliased path is named after its last step, so select('settings->theme') returns theme, and as names it anything else.

Changed

  • A column is read only from a record's own keys. A column named after a built-in object property, such as constructor, now reads as missing instead of reaching the prototype.

2.2.1

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 26 Sep 19:31

Fixed

  • A comparison against a null column inside a negated group now stays unknown, as in SQL, so the record is excluded. whereNot((query) => query.where('age', '>', 26)) and whereNone(['age'], '>', 26) no longer match a record whose age is null.
  • whereNotIn with a null in the list no longer matches values missing from the list, since comparing against that null is unknown.
  • whereNotBetween with a null bound now matches only values the other bound rules out, and whereBetween with a null bound no longer treats that bound as a real limit.
  • whereNotLike and not like no longer match a value that is not a string, such as a number or a date. Only strings are matched by either form.
  • A date part constraint such as whereYear against a value that holds no date is now unknown rather than false, so negating it inside a group no longer matches.
  • Comparing against null with any operator other than equality or inequality, such as where('age', '>', null), is now unknown and matches nothing, including when negated.

Changed

  • where('age', null) is now short for whereNull('age'), and where('age', '!=', null) for whereNotNull('age'). This covers =, ==, ===, !=, <> and !==, treats undefined like null, and whereNot flips the check. Previously where('age', null) matched nothing.
  • Constraints now follow SQL's three-valued logic through nested groups, negation, in lists, between bounds and like patterns. Queries that relied on these matching null or non-string values will return fewer records. Use whereNull, whereNotNull or orWhereNull to ask for null values explicitly.

2.2.0

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 26 Sep 19:02

Added

  • reorder(column?, direction?) removes existing orders, including a random one, and can set a new one.
  • inRandomOrder() returns records shuffled. It applies to get, first, chunk, each, lazy and joined queries. With a limit or offset, update, delete, increment and decrement pick their records at random.
  • whereTime(column, operator?, value) constrains the time of day of a date column, read in local time. HH:MM is treated as HH:MM:00.
  • whereAny, whereAll and whereNone apply one comparison across several columns.

Changed

  • dump() output now includes a random field.

2.1.1

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 26 Sep 16:41

Changed

  • dump() now prints the query's joins and transaction as well, so a joined query no longer dumps as if it read a single table.

Fixed

  • chunk, each and lazy no longer deliver records that stopped matching the query after the walk began. The records that match are still decided when the walk starts, and each page is still fetched fresh. What's new is that a record changed so it no longer matches is now left out, the same as a deleted record already was. As a result, any page may be shorter than the requested size. chunk never passes an empty page to its callback, and its page numbers count only the pages delivered.

2.1.0

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 26 Sep 10:48

Added

  • database-version-changed event, dispatched when another tab upgrades or deletes the database a
    connection holds open. Previously the connection closed its handle silently, and the application
    only found out when its next query failed with MigrationMismatchException. The event carries
    database and version, where version is the version the other tab is opening, or null when
    it is deleting the database.
  • DB.onDatabaseVersionChanged() to listen for it, and the DatabaseVersionChanged class exported
    from the package.

The event is dispatched after the connection has closed its handle, so the other tab's upgrade is
never blocked while listeners run. Reloading the page is the right response. Querying again reopens
the database at the older version and fails:

DB.onDatabaseVersionChanged((event: DatabaseVersionChanged): void => {
    if (confirm('A new version is available. Reload now?')) {
        location.reload();
    }
});

2.0.2

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 25 Sep 14:42

Fixed

  • update, delete, increment and decrement with an orderBy and a limit or offset now touch the records that order selects. Before, when no index served the order, they picked records by key instead.
  • A limited write through several keys, such as whereIn('id', [1, 2, 3]).limit(1).delete(), now stops at the limit instead of touching every match.

Upgrading

Ordered writes with a limit or offset may now change or delete different records than they did in 2.0.1. Check any code that relied on the old behavior.

2.0.1

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 17 Sep 08:28

Fixed

  • where, orWhere, whereNot, having and orHaving now keep an explicit operator when the value passed is undefined. Previously where('role', '!=', undefined) was read as role = '!='.

Changed

  • Operators are now type checked. where, having, whereColumn, join, leftJoin, rightJoin and Join.on suggest the supported operators, and a call with an unsupported operator, or one typed as a plain string, no longer compiles.
  • The README now covers events and the query log in separate sections, with a table listing every event key, its class and the properties it carries.

2.0.0

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 16 Sep 12:18

Breaking

  • A migration's default name is now its class name in snake case, the way Laravel names a migration file. CreateUsersTable is recorded as create_users_table instead of CreateUsersTable.

  • A database migrated with 1.0.0 recorded the old class names, so it will throw MigrationMismatchException on its next boot. To keep an existing database working, override name() on each migration that already ran and return the name it was recorded under:

    class CreateUsersTable extends Migration {
        override name(): string {
            return 'CreateUsersTable';
        }
    }
  • An overridden name() is still used as is.

Changed

  • DB.status(), DB.migrate(), DB.fresh() and the migration events now report migration names in snake case.

1.0.0

Choose a tag to compare

@BJNSTNKVC BJNSTNKVC released this 15 Sep 20:36

First stable release.