Все значимые изменения в этом проекте будут отражены в этом файле.
Участники: Пожалуйста, добавьте свои изменения в CHANGELOG-Unreleased.md
getJSIModulePackage()
переопределение в вашем MainApplication.{java,kt}
и добавьте new WatermelonDBJSIPackage()
в getPackages()
переопределение вместо него. Подробности см. в документации по установке.Database#experimentalIsVerbose
unsafeExecuteSql
миграция теперь проверяется для завершения точкой с запятой (#1811)table#id
проблемной записиbetter-sqlite3
до версии 11.xИсправлен пропущенный журнал изменений для выпуска 0.27## 0.27 - 2023-08-29
Удалены устаревшие модули React Native для Swift и Kotlin
После добавления новых Native Modules в версии 0.26 мы удаляем старые реализации. Мы ожидаем, что это упростит процесс установки и устранит множество проблем совместимости и конфигурации из-за несоответствий версий Kotlin и проблем CocoaPods-Swift при использовании use_frameworks!
или Expo.
Экспериментальная поддержка React Native для Windows
WatermelonDB теперь имеет экспериментальную поддержку для React Native для Windows. Подробности см. в документации по установке.
Введение Watermelon React
Все помощники React/React Native для Watermelon теперь доступны из нового каталога @nozbe/watermelodb/react
:
DatabaseProvider
, useDatabase
, withDatabase
withObservables
- пакет @nozbe/with-observables
устарел и теперь включен в WatermelonDBcompose
, withHooks
<WithObservables />
, версия компонента для HOC withObservables
. Полезно, когда наблюдаемое значение локализовано небольшой частью большого компонента, так как можно легко ограничить перерenderинг части компонента при изменении значения без необходимости выделения нового компонента. Импорты из предыдущего @nozbe/watermelondb/DatabaseProvider
и @nozbe/watermelondb/hooks
устарели и будут удалены в будущей версии.Введение Watermelon Diagnostics
Все средства отладки/разработки/диагностики для Watermelon теперь доступны из нового каталога @nozbe/watermelondb/diagnostics
:- НОВОЕ: censorRaw
— принимает RawRecord/DirtyRaw
и цензурирует его строковые значения, сохраняя идентификаторы, _status, _changed и числовые/булевые значения. Полезно при просмотре содержимого базы данных в контексте, который может раскрыть конфиденциальную информацию пользователя.
diagnoseDatabaseStructure
— анализирует базу данных для поиска несоответствий, таких как сиротские записи (belongs_to
отношения на модели, указывающие на записи, которые не существуют) или сломанный LokiJS база данных. Используйте это для поиска ошибок в вашей модели данных.diagnoseSyncConsistency
— сравнивает локальную базу данных с серверной версией (содержимое первого полного синхронизации) для поиска несоответствий, пропущенных и лишних записей. Используйте это для поиска ошибок в реализации вашего синхронного бэкэнда.@nozbe/with-observables
больше не является зависимостью WatermelonDB. Измените ваши импорты на import { withObservables } from '@nozbe/watermelondb/react'
Изменения, которые маловероятно вызовут проблемы:- [iOS] Если в вашем приложении на Swift используется import WatermelonDB
(для Turbo синхронизации), удалите его и замените на #import <WatermelonDB/WatermelonDB.h>
в заголовочном файле моста.
[iOS] Если вы используете _watermelonDBLoggingHook
, удалите его. В настоящее время замена не предоставляется; свободно вносите свой вклад, если вам это нужно.
[iOS] Если вы используете -DENABLE_JSLOCK_PERFORMANCE_HACK
, удалите его. JSLockPerfHack уже долгое время не работал, и теперь он удален. Пожалуйста, создайте задачу, если вы зависели от него.### Устаревшие импорты
Импорты из @nozbe/watermelondb/DatabaseProvider
и @nozbe/watermelondb/hooks
. Измените на @nozbe/watermelondb/react
@experimentalFailsafe
, который можно применить перед @relation/@immutableRelation
, чтобы если отношение указывало на запись, которая не существует, .fetch()/.observe()
возвращали undefined
вместо выброса ошибкиCannot read property 'getRandomIds' of null
. Эта ошибка возникала, если нативные модули были некорректно установлены, однако местоположение ошибки вызывало много путаницы.## 0.26 - 2023-04-28Новые встроенные модули
Мы переходим к адаптерам SQLite для React Native из Kotlin и Swift к Java и Objective-C.
Это небольшая часть WatermelonDB, но она отвечает за большую долю возникающих проблем, таких как конфликты версий Kotlin, сбои сборки Expo, проблемы с CocoaPods use_frameworks!. Это усложняет установку и обновление библиотеки для пользователей. Это усложняет поддержку. Swift плохо работает с устаревшей системой Native Module React Native, а также не может взаимодействовать чисто с C++ (JSI/Новой архитектурой) без использования Objective-C++.
Другими словами, в контексте библиотеки React Native, преимущества этих современных, более удобных языков
значительно перевешивают недостатки. Поэтому мы (@radex & @rozpierog) решили переписать реализации для iOS и Android
на Objective-C и Java соответственно.0.26 — это переходный выпуск, содержащий обе реализации. Если вы найдете регрессию, вызванную новым мостом,
передайте {disableNewBridge: true}
в new SQLiteAdapter()
и создайте задачу.
Планируется удаление старой реализации в выпусках 0.27 или 0.28.
Новая документация
У нас есть совершенно новая страница документации, созданная с помощью Docusaurus (внесённая @ErickLuizA).
Мы планируем расширить руководства, добавить типы к примерам и добавить полноценную справку по API, но нам нужна ваша помощь для этого! Смотрите: https://github.com/Nozbe/WatermelonDB/issues/1481
[iOS] Вам следует удалить импорт WatermelonDB's SupportingFiles/Bridging.h
из вашего проекта Bridging.h
.
Если удаление вызывает проблемы сборки, пожалуйста, создайте задачу.
[iOS] В вашем Podfile замените предыдущие импорты WatermelonDB следующим образом:
# Отмените эту строку, если вы не используете автоматическое связывание
# pod 'WatermelonDB', path: '../node_modules/@nozbe/watermelondb'
# WatermelonDB зависимость
pod 'simdjson', path: '../node_modules/@nozbe/simdjson', modular_headers: true
Удалены функции, устаревшие более 2 лет:
Collection.unsafeFetchRecordsWithSQL()
. Используйте .query(Q.unsafeSqlQuery('select * from...')).fetch()
вместо.Database.action()
. Используйте Database.write()
вместо..subAction()
. Используйте .callWriter()
вместо.@action
декоратор. Используйте @writer
вместо.### Устаревшие функцииexperimentalUnsafeNativeReuse
в SQLiteAdapter. Подробнее см. src/adapters/sqlite/type.js
Q.and(conditions)
, Q.or(conditions)
, collection.query(conditions)
, query.extend(conditions)
помимо распаковки нескольких аргументовrandomId
использует лучший генератор случайных чисел@nozbe/with-observables@1.5.0
query.batch([model, falsy])
больше не вызывает ошибкуQ.and, Q.or, Collection.query, Database.batch
вместо одного массиваrandomId()
теперь в 2 раза быстрее на Chrome, в 10 раз быстрее на Safari, в 2 раза быстрее на iOS (Hermes)randomId
: теперь также генерирует заглавные буквыУпрощена интеграция CocoaPods/iOS
Улучшены документы: версии SQLite, объявления Flow, установка
Улучшены диагностические предупреждения и ошибки: JSI, Writer/Reader
Удалены старые диагностические предупреждения, которые больше не актуальны: несколько Q.on()
, Database
, LokiJSAdapter
, SQLiteAdapter
Обновлен flow-bin
до 0.200. Это не должно повлиять на вас, но может исправить или сломать Flow, если WatermelonDB не установлен в режиме [declarations]
Обновлен @babel/runtime
до 7.20.13
Обновлен rxjs
до 7.8.0
Обновлен sqlite
(SQLite используется на Android в режиме JSI) до 3.40.1
Обновлен simdjson
до 3.1.0### Внутренние изменения
Улучшено QueryDescription, структура папки ios, реализация JSI путём разделения на меньшие части.
[Android] [jsi] Упрощена структура CMakeLists
Улучшена скрипт выпуска
DirtyRaw
на { [key: string]: any }
(от Object)Record ID xxx#yyy был отправлен через мост, но он не кэширован
Q.where(xxx, undefined)
теперь будет выбрасывать ошибку. Это исправление бага, так как сравнение сundefined никогда не было разрешено и либо вызывало ошибку, либо давало неверный результат в некоторых случаях. Однако, это может теоретически сломать приложение, которое зависело от существующего бага поведения
[JSI+Swift] Если вы используете watermelondbProvideSyncJson()
native iOS API, вам может потребоваться добавить import WatermelonDB
### Новые возможности
[adapters] Объекты адаптеров теперь могут быть различены путём проверки их static adapterType
[Query] Новый запрос Q.includes('foo')
для чувствительного к регистру сравнения строк
[adapters] Объекты адаптеров теперь возвращают dbName
[Sync] Замена Sync — новая продвинутая функция синхронизации. Сервер теперь может отправить полное набор данных (такое же, как
во время первоначальной синхронизации) и указать с помощью { experimentalStrategy: 'replacement' }
, что вместо применения разницы,
локальная база данных должна быть заменена отправленным набором данных. Локальные записи, отсутствующие в наборе изменений,
будут удалены. Однако, в отличие от очистки базы данных и повторного входа, неподтверждённые локальные изменения
(к записям, которые сохраняются после замены) сохраняются. Это полезно для восстановления от повреждённой локальной базы данных,
или как хак для обработки очень больших состояний изменений, когда сервер не знает, как эффективно отправить инкрементальные изменения,
и хочет отправить полный набор данных вместо этого. Смотрите документацию для более подробной информации.
[Sync] Добавлен обратный вызов onWillApplyRemoteChanges
@json
, теперь с необязательным параметром { memo: true }
unsafeExecute
, свойство localStorage
к базе данных<cassert>
Model.experimentalMarkAsDeleted/experimentalDestroyPermanently()
в некоторых случаяхwithObservables
Q.experimentalSortBy
, Q.experimentalSkip
, Q.experimentalTake
переименованы соответственно в Q.sortBy
, Q.skip
, Q.take
rxjs
в вашем приложении, это не относится к вам. Если вы импортируете, прочитайте критические изменения RxJS 7: https://rxjs.dev/deprecations/breaking-changes
database.localStorage
sortBy, skip, take теперь доступны в LokiJSAdapter
Недолгоживущие записи. Читаемые только для чтения записи, которые не могут быть сохранены в базе данных, обновлены или удалены и существуют только пока вы сохраняете ссылку на них в памяти, могут быть созданы с помощью collection.disposableFromDirtyRaw()
. Это полезно, когда вы добавляете функции, доступные только онлайн, в приложение, которое обычно работает в оффлайн-режиме.
[Синхронизация] Параметр experimentalRejectedIds
теперь доступен в ответе на отправку для частичного отказа от успешной синхронизации### Исправления
Исправление проблемы при использовании Headless JS на Android с включенным режимом JSI — передайте usesExclusiveLocking: true
в SQLiteAdapter для включения
Исправление аннотаций TypeScript для Collection и адаптеров/sqlite
Это крупное обновление WatermelonDB с новыми продвинутыми возможностями, значительными улучшениями производительности и важными исправлениями для JSI на Android.
Не бойтесь длинного списка критических изменений — они либо простые замены, либо изменения внутренних механизмов, которые вы, скорее всего, не используете. Обновление до версии 0.23 не должно занять у вас более 15 минут.### КРИТИЧЕСКИЕ ИЗМЕНЕНИЯ- Изменение установки для iOS. Вам нужно добавить эту строку в ваш Podfile: pod 'simdjson', path: '. . /node_modules/@nozbe/simdjson'
new Database({ actionsEnabled: false })
был удален. Действия всегда включены.new SQLiteAdapter({ synchronous: true })
был удален. Вместо этого используйте { jsi: true }
.Q. unsafeLokiFilter
была удалена. Вместо неё используйте Q. unsafeLokiTransform((raws, loki) => raws. filter(raw => . . . ))
.Query. hasJoins
была удалена.LokiJSAdapter
:
indexedDBSerializer
-> extraIncrementalIDBOptions: { serializeChunk, deserializeChunk }
onIndexedDBFetchStart
-> extraIncrementalIDBOptions: { onFetchStart }
onIndexedDBVersionChange
-> extraIncrementalIDBOptions: { onversionchange }
autosave: false
-> extraLokiOptions: { autosave: false }
Model. _isCommited
, . _hasPendingUpdate
, . _hasPendingDelete
были удалены и заменены на Model. _pendingState
Collection. unsafeClearCache()
больше не доступенadapter. setLocal()
, теперь проверяются на то, что они являются строками. Это фактический исправление ошибки, так как локальное хранилище всегда было документировано как принимает только строки. Однако приложения могут полагаться на отсутствие этой проверки. Добавление этой проверки было необходимо для обеспечения последовательного поведения между SQLiteAdapter и LokiJSAdapter.- unsafeSql
, передаваемое в appSchema
, теперь будет вызываться также при удалении и последующем воссоздании всех индексов базы данных в больших пакетах. Был добавлен второй аргумент, чтобы вы могли различать эти случаи. Подробнее см. документацию схемы.record._raw._changed
и record._raw._status
(также известное как record.syncStatus
) изменилось. Это маловероятно является разрывом совместимости, если вы не пишете свой собственный модуль синхронизации или не полагаетесь на эти низкоуровневые детали.
_changed
всегда было пустым при _status=created
. Теперь, _changed
не заполняется во время первоначального создания записи, но последующее обновление добавляет измененные поля в _changed
. Это изменение было необходимо для исправления старой ошибки синхронизации. ### Устаревшие функции- database.action(() => {})
теперь устарел. Используйте db.write(() => {})
вместо (или db.read(() => {})
, если вам нужна только согласованность, но вы не пишете никаких изменений в БД)@action
теперь устарел. Используйте @writer
или @reader
вместо.subAction()
теперь устарел. Используйте .callReader()
или .callWriter()
вместоCollection.unsafeFetchRecordsWithSQL()
теперь устарел. Используйте collection.query(Q.unsafeSqlQuery("select * from...")).fetch()
вместо.db. write(writer => { ... writer. batch() })
- теперь вы можете вызывать метод batch
на интерфейсе, переданном в блок writerПолучение ID записей и сырого незащищенного контента. Теперь вы можете оптимизировать получение запросов, которые требуют только ID, а не полных закэшированных записей:
await query. fetchIds()
вернет массив ID записейawait query. unsafeFetchRaw()
вернет массив незащищенных, незащищенных объектов (используйте вместе с Q. unsafeSqlQuery
для исключения ненужных или включения дополнительных колонок)adapter. queryIds()
, adapter. unsafeQueryRaw
Сырое SQL-запрос. Новый синтаксис для выполнения незащищенных сырых SQL-запросов:
collection. query(Q. unsafeSqlQuery("select * from tasks where foo = ? ", ['bar'])). fetch()
. fetchCount()
, . fetchIds()
на SQL-запросахНезащищенное выполнение SQL-запроса. Теперь вы можете выполнять произвольные SQL-запросы (SQLiteAdapter) или прямой доступ к объекту Loki (LokiJSAdapter) с помощью adapter. unsafeExecute
— см. документацию для более подробной информации
Ускоренный вход. Теперь вы можете ускорить начальную (входную) синхронизацию до 5,3 раз с помощью Turbo Login. Подробнее см. документацию по синхронизации- Новый диагностический инструмент - debugPrintChanges. Подробнее см. документацию по синхронизации### Улучшение производительности — Порядок Q. конструкций в запросе теперь сохраняется — ранее конструкции могли перестраиваться и создавать недопустимый запрос
[SQLite] adapter.batch()
с большим количеством созданных/обновленных/удаленных записей теперь работает на 16–48% быстрее
[LokiJS] Запросы и поиск теперь выполняются быстрее — избыточное копирование данных пропущено
[jsi] При большом количестве возвращаемых записей запросы на JSC (iOS) становятся на 15–30% быстрее
[jsi] Быстрое создание пакета до 52% — это улучшение сверх того, что указано выше!
Устранена производительная проблема, которая вызывала избыточное перерendering наблюдаемых элементов в списке с использованием .observeWithColumns()
незадолго до их удаления из списка### Изменения
Все логи консоли Watermelon теперь начинаются с тега 🍉
Добавлены дополнительные защиты от неправильного использования писателей/читателей (ранее действий)
Запросы с несколькими верхнеуровневыми Q.on('table', ...)
теперь вызывают предупреждение. Вместо этого используйте синтаксис Q.on('table', [условие1, условие2, ...])
.
[jsi] Теперь используется режим WAL
[jsi] Исправлено некорректное отображение ошибок при некоторых ошибках sqlite
[jsi] Исправлена проблема, при которой приложение падало на Android/Hermes при перезагрузке
[jsi] Исправлены ошибки ввода-вывода на Android
["sync"] Исправлена долгосрочная ошибка, которая приводила к потере последних изменений записей, созданных до синхронизации и обновленных во время синхронизации, при последующей синхронизации### Внутренние изменения
Внутренние изменения в SQLiteAdapter:
.batch
больше недоступен в реализации для iOS.batch/.batchJSON
изменён.getDeletedRecords
, destroyDeletedRecords
, setLocal
, removeLocal
больше недоступныКодированные схемы SQLiteAdapter изменены
В LokiJSAdapter произведено много внутренних изменений
experimentalUseJSI: true
переименована в jsi: true
Q.unsafeLokiFilter
теперь устарел и будет удалён в будущих версиях.
Используйте Q.unsafeLokiTransform((raws, loki) => raws.filter(raw => ...))
вместо него.jsi: true
теперь работает на Android — см. документацию для информации о настройкеwithObservables
pushChanges
теперь является необязательным, локальные изменения не будут вычисляться, если он не указан.withObservables
теперь является зависимостью WatermelonDB для более простой установки и последовательных обновлений. Вы можете (и обычно должны) удалить @nozbe/with-observables
из вашего package.jsonQuery._sql()
только для разработки для быстрого извлечения SQL из запросов для целей отладки### Исправления- Устранение проблемы с подъемом статических данных в withDatabase()
для нереактивных компонентовprocess
, которая может вызвать ошибки приложения в некоторых окружениях (например, webpack5)fetch
) вместе с Collection.unsafeFetchRecordsWithSQL
— @jspizziriwithObservables
больше не должна вызывать проблем с RxJS, так как больше не импортирует библиотеку RxJSonSetUpError
и onIndexedDBFetchStart
в LokiAdapterOptions
; исправлено сообщение об ошибке Typescript — @3DDariouseWebWorker
и useIncrementalIndexedDB
из LokiAdapterOptions
— @3DDariouseWebWorker
и useIncrementalIndexedDB
теперь обязательны (ранее пропуск этих опций вызывал только предупреждение)Model.update
теперь возвращает обновленную запись[адаптеры] Добавлена опция onSetUpError: Error => void
для обоих адаптеров SQLiteAdapter
и LokiJSAdapter
. Укажите эту опцию для перехвата ошибок инициализации и предложить пользователю перезагрузить или выйти из системы
[LokiJS] Добавлены новые опции extraLokiOptions
и extraIncrementalIDBOptions
[Android] Поддержка автоматической связи теперь доступна.
<= v0.21.0
И используете версию React Native, поддерживающую автоматическую связь, вам потребуется удалить конфигурацию, связанную с ручной связью WatermelonDB.[LokiJS] Улучшение производительности запуска приложения
useWebWorker: true
и useIncrementalIndexedDB: false
теперь устарели. Если вы используете эти возможности, пожалуйста, создайте задачу!log
, передаваемый в синхронизацию, теперь содержит более полезную диагностическую информациюsynchronous:true
теперь устарела и будет заменена на experimentalUseJSI: true
в будущем. Пожалуйста, протестируйте, компилируется ли ваше приложение и работает ли оно хорошо с experimentalUseJSI: true
, и если нет — создайте задачу!experimentalNestedJoin
и раздел unsafeSqlExpr
[LokiJS] Устранена проблема, при которой IndexedDB могла повредиться со временем
[Устойчивость] Добавлены дополнительные диагностики для случаев, когда вы сталкиваетесь с ошибкой Record ID aa#bb был отправлен через мост, но он не кэширован
, а также добавлен путь восстановления (только для LokiJSAdapter). Пожалуйста, создайте задачу, если вы столкнетесь с этой проблемой!
[TypeScript] Устранена проблема типа для OnFunction, чтобы принимать and
в join
[TypeScript] Устранена проблема типа database#batch(records)
для аргумента records
, чтобы принимать смешанные типы### Внутренние изменения
Добавлен экспериментальный режим, который обнаруживает поврежденное состояние базы данных, предотвращает дальнейшие изменения и уведомляет пользователя
Эта версия случайно сломала RxJS для некоторых приложений, использующих with-observables
. Если у вас возникла такая проблема, пожалуйста, обновите @nozbe/with-observables
до последней версии.
Q.like
для многострочных строк в вебеexperimentalUseJSI
включена на Android. Однако, она требует некоторых настроек приложения, которые ещё не документированы — следите за новыми выпусками.unsafeSql
в схемном билдере и шагах миграций для модификации сгенерированного SQL для установки базы данных или выполнения миграций. Также есть новый шаг миграции unsafeExecuteSql
. Пожалуйста, используйте это только если вы знаете, что делаете — вам этого не потребуется в 99% случаев. Подробнее см. документацию по схемам и миграциям.onIndexedDBFetchStart
и indexedDBSerializer
в LokiJSAdapter
. Эти опции могут использоваться для улучшения времени запуска приложения. Подробнее см. src/adapters/lokijs/index.js
.Еще одна версия WatermelonDB после недели? Да! И она полна новых возможностей!
[Запрос] Запросы Q.on
стали гораздо гибче. Ранее они могли использоваться только на верхнем уровне запроса. Подробнее см. Документацию. Теперь вы можете:
Передавать несколько условий для связанного запроса, например:
collection.query(Q.on('projects', [Q.where('foo', 'bar'), Q.where('bar', 'baz')]))
Размещать Q.on
глубже внутри запроса (вложенные внутри Q.and()
, Q.or()
). Однако вам необходимо явно указать все таблицы, которые вы объединяете, в начале запроса, используя: Q.experimentalJoinTables(['join_table1', 'join_table2'])
.
Вкладывать условия Q.on
внутри других Q.on
, чтобы сделать условие для внучатого уровня. Для этого требуется передать Q.experimentalNestedJoin('parent_table', 'grandparent_table')
в начале запроса.
[Запрос] Введены Q.unsafeSqlExpr()
и Q.unsafeLokiExpr()
, чтобы позволить добавлять части запросов, которые не поддерживаются языком запросов WatermelonDB, без использования unsafeFetchRecordsWithSQL()
. Подробнее см. Документацию.
[Запрос] Q.unsafeLokiFilter((rawRecord, loki) => boolean)
теперь можно использовать как выходной механизм для создания запросов с LokiJSAdapter, которые иначе невозможны (например, сравнение столбцов между несколькими таблицами). Подробнее см. Документацию.
Query.hasJoins
устарелQ.experimentalTake
/ Q.experimentalSkip
, в настоящее время сломаны — ранее они возвращали неверные результаты, но теперь они выбрасывают ошибку, чтобы избежать путаницы. Пожалуйста, внесите свой вклад для исправления корневой причины!### Исправления- [TypeScript] Исправлены типы RelationQueryDescription
.[Синхронизация] Введены миграционные синхронизации — это позволяет полностью согласованной синхронизации при миграции между версиями схемы. Ранее не было механизма для постепенного получения всех удалённых изменений в новых таблицах и столбцах после миграции — поэтому локальная копия была скорее всего неконсистентной, требуя повторной авторизации. После внедрения миграционных синхронизаций, Watermelon Sync будет запрашивать у сервера все недостающие данные. Подробнее см. документацию по синхронизации.
[iOS] Введено новое нативное интегрирование базы данных SQLite, переписанное с нуля на C++, основанное на JavaScript Interface (JSI) React Native. Это следует считать экспериментальным, однако мы планируем сделать его основной (и в конечном итоге единственной) реализацией. В последующих выпусках будет введена версия для Android.
Новый адаптер до 3 раз быстрее, чем ранее самая быстрая опция `synchronous: true`, однако этот прирост производительности достигается с помощью ещё не опубликованных патчей React Native.
Чтобы попробовать JSI, добавьте `experimentalUseJSI: true` в конструктор `SQLiteAdapter`.- [Запрос] Добавлены методы `Q.experimentalSortBy(sortColumn, sortOrder)`, `Q.experimentalTake(count)`, `Q.experimentalSkip(count)` (доступны только с `SQLiteAdapter`) - @Kenneth-KT
Теперь Database.batch()
можно вызывать с одним массивом моделей
[DX] Database.get(tableName)
теперь является сокращением для Database.collections.get(tableName)
[DX] Запрос теперь является thenable — вы можете использовать await query
и await query.count
вместо await query.fetch()
и await query.fetchCount()
[DX] Отношение теперь является thenable — вы можете использовать await relation
вместо await relation.fetch()
[DX] Выходные данные collection.db
и model.db
теперь являются сокращениями для доступа к объекту Database### Изменения
[Усиление безопасности] Начальные значения столбцов и таблиц, начинающиеся с __
, имена свойств объектов (например, constructor
) и некоторые зарезервированные ключевые слова теперь запрещены
[UX] [Усиление безопасности] Методы построителя QueryDescription выполняют более строгие проверки типов, что позволяет ловить больше ошибок и предотвращает передачу незащищенных данных пользователя в методы построителя запросов
[UX] [Усиление безопасности] Адаптеры проверяют рано, являются ли имена таблиц корректными
[UX] Метод Collection.find быстрее отображает ошибку, если передано очевидно некорректное значение ID
[UX] Инициализация базы данных с некорректными классами моделей теперь показывает полезное сообщение об ошибке
[UX] DatabaseProvider теперь отображает более полезное сообщение об ошибке при некорректном использовании
[Синхронизация] Синхронизация больше не завершается ошибкой, если pullChanges возвращает коллекции, которые не существуют на фронтенде — вместо этого отображается предупреждение. Это сделано для уменьшения вероятности ошибок при создании обратно совместимых серверных приложений
[Синхронизация] [Документация] Документация по синхронизации переписана и теперь ближе к детализированному формальному спецификации
[Усиление безопасности] database.collections.get() лучше проверяет переданные значения- [Усиление безопасности] Предотвращает передачу опасных строковых значений как аргументов имени столбца/таблицы в QueryDescription### Исправления- [Синхронизация] Исправлено исключение RangeError: Maximum call stack size exceeded
, возникающее при синхронизации больших объемов данных - @leninlin
[iOS] Исправлена ошибка, которая могла привести к завершению операции базы данных с ошибкой (6) SQLITE_LOCKED
[iOS] Исправлено сообщение "jsi/jsi.h" file not found при сборке на уровне потребителя. Добавлен путь $(SRCROOT)/../../../../../ios/Pods/Headers/Public/React-jsi
в Header Search Paths (issue #691) - @victorbutler
[Нативная] Использование ключевых слов SQLite в качестве имен таблиц или колонок больше не приводит к аварийному завершению программы
Исправлены потенциальные проблемы при подписке на базу данных, коллекцию, модель, запросы, передача функции подписчика с одинаковым идентификатором более одного раза
Это исправление безопасности для уязвимости, которая может привести к удалению всех или части данных пользователя при использовании специально созданных идентификаторов записей. Более подробная информация доступна через GitHub Security Advisory
Database.unsafeResetDatabase()
теперь менее опасен — выявляет больше ошибок приложения[TypeScript] Добавлено определение типа для setGenerator
.
[TypeScript] Исправлены типы декораторов.
[TypeScript] Добавлены тесты для проверки типов.
Исправлена ошибка в документации по использованию.
[TypeScript] Исправлены типы изменений.### Внутренние изменения
[SQLite] Добавлена инфраструктура для будущего адаптера JSI
experimentalUseIncrementalIndexedDB
переименован в useIncrementalIndexedDB
database.adapter
возвращает новый DatabaseAdapterCompat
, который имеет ту же структуру, что и старый API адаптера. Вы можете использовать database.adapter.underlyingAdapter
, чтобы получить обратно SQLiteAdapter
/ LokiJSAdapter
Collection.fetchQuery
и Collection.fetchCount
удалены. Пожалуйста, используйте Query.fetch()
и Query.fetchCount()
.### Новые возможностиsynchronous
в адаптер: new SQLiteAdapter({ ..., synchronous: true })
.
При включении операций с базой данных будут блокировать поток JavaScript. Действия адаптера завершатся в следующем микроинтервале, что упрощает создание интерфейсов без мерцаний. Адаптер вернётся к асинхронным операциям, когда синхронный адаптер недоступен (например, при удалённой отладке).LokiJSAdapter
добавлена новая опция onQuotaExceededError?: (error: Error) => void
.
Эта функция вызывается, когда основной IndexedDB столкнулся с ошибкой превышения квоты (закончилось выделенное место на диске для приложения).
Это означает, что приложение больше не сможет сохранять данные или будет использовать только временную базу данных в памяти.
Обратите внимание, что эта опция работает только при useWebWorker: false
.### Изменения- [Производительность] Внутренняя реализация Watermelon была переписана так, чтобы не зависеть от Promise и позволять некоторым вызовам fetch/observe разрешаться синхронно. Не полагайтесь на это — внешний API все еще основан на Rx и Promise и может разрешаться как асинхронно, так и синхронно в зависимости от возможностей. Это является внутренней оптимизацией производительности на данный момент.experimentalUseIncrementalIndexedDB
database.unsafeResetDatabase()
model.experimentalSubscribe((isDeleted) => { ... })
как альтернатива на чистом JavaScript к Rx-основному методу model.observe()
. В отличие от последнего, он не уведомляет подписчика сразу после подписки.collection.experimentalSubscribe((changeSet) => { ... })
как альтернатива на чистом JavaScript к Rx-основному методу collection.changes
(вы, вероятно, не должны использовать этот API вообще).database.experimentalSubscribe(['table1', 'table2'], () => { ... })
как альтернатива на чистом JavaScript к Rx-основному методу database.withChangesForTables()
. В отличие от последнего, experimentalSubscribe
уведомляет подписчика только один раз после пакета, который делает изменения во множестве подписанных коллекций. Он также не уведомляет подписчика сразу после подписки и не отправляет детали об изменениях, только сигнал.experimentalDisableObserveCountThrottling()
к @nozbe/watermelondb/observation/observeCount
, глобально отключающий торможение наблюдения количества. Мы считаем, что торможение на уровне WatermelonDB не является хорошей функцией и будет удалено в будущем выпуске — и будет лучше реализовано на уровне приложения, если это необходимо.query.experimentalSubscribe(records => { ... })
, query.experimentalSubscribeWithColumns(['col1', 'col2'], records => { ... })
, и query.experimentalSubscribeToCount(count => { ... })
.Это массовое обновление WatermelonDB! 🍉
До 23 раз быстрее синхронизация. Вы правильно это услышали. Мы сделали большие улучшения производительности. В наших тестах, при массовой синхронизации (первый вход, 45 МБ данных / 65 К записей) мы получили ускорение скорости:
Ожидайте больше улучшений в последующих выпусках!
Улучшенный адаптер LokiJS. Возможность отключения веб-работников, важное исправление для Safari 13, лучшая производительность,
и теперь работает в режимах приватного просмотра. Мы рекомендуем добавить опции useWebWorker: false, experimentalUseIncrementalIndexedDB: true
к конструктору LokiJSAdapter
, чтобы воспользоваться улучшениями, но пожалуйста, прочитайте дальнейший список изменений, чтобы понять последствия этого.
Чистые SQL запросы теперь доступны на iOS и Android благодаря сообществу
Улучшенная поддержка TypeScript — благодаря сообществу
bool
удален — пожалуйста, замените на boolean
experimentalSetOnlyMarkAsChangedIfDiffers(false)
удаленаCollection.unsafeFetchRecordsWithSQL()
. Вы можете использовать его для получения записей с помощьючистых SQL запросов на iOS и Android. Пожалуйста, будьте осторожны, чтобы избежать SQL-инъекций и других проблем чистых запросов.
[LokiJS] Введен новый параметр new LokiJSAdapter({ ..., experimentalUseIncrementalIndexedDB: true })
.
При активации база данных будет сохраняться в IndexedDB браузера с использованием нового адаптера, который сохраняет только измененные записи, а не всю базу данных. Это обходит серьезную ошибку в Safari 13 (https://bugs.webkit.org/show_bug.cgi?id=202137), которая вызывает быстрое увеличение размера базы данных до гигабайт мусора
Это также улучшает производительность при частичном сохранении, хотя первая загрузка страницы или очень большие сохранения могут быть немного медленнее.
Это предназначено стать новым стандартным параметром, но он не обратно совместим (если активирован, старая база данных будет потеряна). Вы можете внести свой вклад в автоматическую миграцию кода. Обратите внимание, что этот параметр всё ещё экспериментальный и может измениться в непредсказуемом виде в любое время.
[LokiJS] Введена новая опция new LokiJSAdapter({ ..., useWebWorker: false })
. Ранее веб-работеры всегда использовались с LokiJSAdapter
. Хотя использование веб-работеров может иметь некоторые преимущества по производительности, отключение их может привести к снижению потребления памяти, уменьшению задержек и упрощению отладки. YMMV.
[LokiJS] Добавлена опция onIndexedDBVersionChange
к LokiJSAdapter
. Это обратный вызов, который вызывается, когда внутренняя версия IDB изменяется (скорее всего, база данных была удалена в другом вкладке браузера). Передайте обратный вызов для принудительного выхода из этой копии приложения. Обратите внимание, что это работает только при использовании incrementalIDB и отсутствии использования веб-работеров.
[Модель] Добавлен метод Model._dangerouslySetRawWithoutMarkingColumnChange()
. Вы, скорее всего, не должны использовать его, но если вы знаете, что делаете и хотите обновлять записи из сервера в реальном времени без отметки записи как изменённой, это полезно.
[Коллекция] Добавлен метод Collection.prepareCreateFromDirtyRaw()
.
@json декоративные функции очистки принимают необязательный второй аргумент, содержащий ссылку на модель.### Исправления- Установлена необходимая версия rambdax
2.15.0 для устранения ошибки консольного логирования. В будущих выпусках мы перейдем на свой форк rambdax
, чтобы избежать подобных проблем в будущем.
[Производительность] [iOS] Ускорение работы с большими пакетами вставок (скорость увеличена в десятки раз)
[Производительность] [iOS] Ускорение кодирования очень больших запросов (с тысячами параметров) в 20 раз
[Производительность] [LokiJS] Ускорение работы с пакетами вставок (время выполнения сокращено на 1,5 секунды для образца вставки 65К записей)
[Производительность] [LokiJS] Различные улучшения производительности
[Производительность] [Синхронизация] Ускорение процесса синхронизации
[Производительность] Ускорение наблюдений
[Производительность] [Android] Ускорение работы с пакетами данных
Исправление сбоев приложения и проблем производительности, вызванных условиями гонки в методе Query.observeWithColumns()
[LokiJS] Интерфейс адаптера хранения теперь автоматически выбирается на основе доступности. По умолчанию используется IndexedDB. Однако, если он недоступен (например, в режиме приватного браузера), будет использоваться временный адаптер хранения в памяти.
Отключение консольных логов, связанных с новыми наблюдениями (он никогда не считал все наблюдения), а также времени выполнения запросов/подсчета/пакетов (меры были крайне неточными из-за асинхронности — фактические времена значительно ниже)- [withObservables] Улучшение производительности и удобства отладки (обновите пакет withObservables отдельно)
Улучшение удобства отладки Watermelon — сокращение Rx стеков и добавление имен функций для помощи в понимании стеков вызовов и профилей
[адаптеры] Интерфейс адаптеров изменился. Методы query()
и count()
теперь принимают SerializedQuery
, а метод batch()
принимает TableName<any>
и RawRecord
или RecordId
вместо Model
.
[Typescript] Улучшение типизации
collections
, database
и asModel
в определении типа Model.actionsEnabled
в опциях конструктора Database, так как это обязательно с версии 0. 13. 0.Изменено, как асинхронные функции транслируются в библиотеке. Это может вызвать проблемы на очень старых устройствах Android, но это должно не иметь значения, если вы используете последнюю версию React Native. Пожалуйста, сообщите об ошибке, если вы заметили проблему.
Устранение проброса свойства database
в демонстрационном приложении для веба## 0. 14. 1 - 2019-08-31Критическое исправление для аварийного завершения работы rambdax
[Schema] Обработка недействительного аргумента схемы таблицы в appSchema
[withObservables] Добавлена поддержка TypeScript (история изменений)
[Electron] Избежание ошибки Uncaught ReferenceError: global is not defined
в среде выполнения Electron (#453)
[rambdax] Замена contains
на includes
из-за устаревания contains
https://github.com/selfrefactor/rambda/commit/1dc1368f81e9f398664c9d95c2efbc48b5cdff9b#diff-04c6e90faac2675aa89e2176d2eec7d8R2209
notLike
🎉experimentalMarkAsDeleted
или experimentalDestroyPermanently
[Database] Теперь обязательна передача опции actionsEnabled:
в конструктор Database.
Рекомендуется включить эту опцию:
const database = new Database({
adapter: ...,
modelClasses: [...],
actionsEnabled: true
})
Подробнее о действиях см. docs/Actions.md
. Вы также можете передать false
, чтобы сохранить обратную совместимость, но эта опция будет удалена в будущих версиях.
[Adapters] Опция migrationsExperimental
адаптеров SQLiteAdapter и LokiJSAdapter переименована в migrations
.
prepareMarkAsDeleted
или prepareDestroyPermanently
synchronize()
больше не вызывает вашу функцию pushChanges()
, если нет локальных изменений для отправки. Это должно сэкономить ненужный сетевой трафик. ⚠️ Обратите внимание, что это может быть несовместимостью, если вы полагаетесь на то, что она всегда вызывается.experimentalSetOnlyMarkAsChangedIfDiffers
из @nozbe/watermelondb/Model/index
и вызвать его с (false)
, чтобы вернуть старое поведение, но это будет удалено в будущих версиях -- создайте новый issue, объяснив, почему вам это нужно.import { setGenerator } from '@nozbe/watermelondb/utils/common/randomId'
и затем вызвав setGenerator(newGenerator)
.
Это позволяет WatermelonDB создавать конкретные ID, например, если ваш сервер использует UUID.Database.batch(...)
(false, null, undefined). Это полезно для поддержания чистого кода при выполнении операций условно. (Также работает с model.batch(...)
).@action
на методах любого объекта, который имеет свойство database: Database
,
и декораторы @field @children @date @relation @immutableRelation @json @text @nochange
на любом объекте с свойством asModel: Model
._unsafeBatchPerCollection: true
к synchronize()
. Это приводит к тому, что изменения сервера будут применяться к базе данных в нескольких партиях, а не одной. Это НЕ рекомендуется по причинам надежности и производительности, но это помогает решить проблему памяти, которая может привести к аварийному завершению работы вашего приложения при очень больших синхронизациях (>20,000 записей). Используйте этот флаг только при необходимости. Обратите внимание, что эта опция может быть удалена в любое время, если будет найдено лучшее решение.## 0.12.1 - 2019-04-01[iOS] Исправлена ошибка времени выполнения при сборке с Xcode 10.2 (Swift 5 runtime).
⚠️ Примечание: Вам потребуется обновиться до версии React Native 0.59.3 для использования этого исправления. Если вы не можете обновиться до React Native сейчас, либо используйте Xcode 10.1, либо примените этот патч вручную: https://github.com/Nozbe/WatermelonDB/pull/302/commits/aa4e08ad0fa55f434da2a94407c51fc5ff18e506
synchronize()
для заполнения его диагностической информацией:
const log = {}
await synchronize({ database, log, ...})
console.log(log.startedAt)
useDatabase
для использования контекста базы данных:
import { useDatabase } from '@nozbe/watermelondb/hooks'
const Component = () => {
const database = useDatabase()
}
.d.ts
. Обратите внимание: типы TypeScript в настоящее время неполные и должны использоваться только как руководство. Вклады по улучшению будут очень полезны!
@date
теперь возвращает дату 1 января 1970 года вместо null
, если значение поля в сыром виде равно 0
.
Это считается исправлением ошибки, так как неожиданно получать null
от геттера поля, чья схема столбца не указывает на isOptional: true
.
Однако, если вы полагались на это поведение, это может быть нестабильным изменением.Database.unsafeResetDatabase()
теперь требует выполнения внутри транзакцииunsafeResetDatabase
unsafeResetDatabase()
, что делает сброс базы данных немного безопаснее0.30.0
compile
на implementation
в файле Gradle библиотекиpeerDependency
react-native
до версии 0.57.0
hasUnsyncedChanges()
created
и updated
записямиheader search path
для поддержки выбитого проекта Expo.dbName
адаптера SQLiteAdapter
теперь позволяет передавать абсолютный путь к файлу, а не имяlast_modified
больше не добавляется автоматически ко всем таблицам базы данных. Если вы не используете эту колонку (например, в вашем собственном коде синхронизации), вам ничего делать не нужно. Если же вы используете её, добавьте эту колонку вручную ко всем определениям таблиц в вашей схеме:
{ name: 'last_modified', type: 'number', isOptional: true }
API действий.
Это было фактически выпущено в версии 0.8.0, но теперь документировано. При включении действий все вызовы создания, обновления, удаления и пакетных операций должны быть обёрнуты в действие.
Чтобы использовать действия, вызовите await database.action(async () => { /* выполните записи здесь */ })
, а в методах экземпляров модели вы можете просто декорировать весь метод с помощью @action
.
Это необходимо для Watermelon Sync, а также для обеспечения большей безопасности и согласованности.
Чтобы включить действия, добавьте actionsEnabled: true
к new Database({ ... })
. В будущих выпусках это будет включено по умолчанию, а затем сделано обязательным.
Подробнее см. документацию.
Адаптер Watermelon Sync (Экспериментальный)Добавлена функция synchronize()
, которая позволяет легко добавить полные возможности синхронизации к вашему приложению Watermelon. Вам нужно предоставить два запроса к вашему удалённому серверу, который соответствует протоколу синхронизации Watermelon, и вся клиентская обработка (применение удалённых изменений, разрешение конфликтов, поиск локальных изменений и пометка их как синхронизированных) выполняется Watermelon.Подробнее см. документацию.
Поддержка кэширования для локальных ID на уровне Native
Q.like
- теперь можно выполнять запросы, аналогичные SQL LIKE
DatabaseProvider
и withDatabase
- высокоуровневый компонент для снижения передачи пропсовjsc-android
oneOf()
и некоторые другие ошибки вариативности@nozbe/watermelondb/babel/cjs
/ @nozbe/watermelondb/babel/esm
, поставляемый вместе с Watermelon, устарел и больше не требуется. Удалите его из конфигурации Babel, так как он будет удалён в будущих обновлениях### Переработкаasync
(Web Worker должен стать примерно на 30КБ меньше)Collection
и simpleObserver
для получения изменений в массиве и также добавлены CollectionChangeTypes для различия между различными изменениямиПервое издание WatermelonDB
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )