|
Представляем вам ORMjs
Ссылка на скачку https://www.npmjs.com/package/ormjs
ORMjs это использования стандартных структур языка яваскрипт, таких как классы, для взаимодействия с базой данных. Класс представляет собой аналог коллекции в базе данных, а инстанс класса документ в коллекции. Более подробно вот тут https://ru.wikipedia.org/wiki/ORM Статические методы класса выполняются для работы с колелкцией, а методы инстансов для работы с самим документом. Таким образом, мы работаем с базой, без селекторов или специального языка, А работаем как бы с яваскрипт обьектами и их методами. А оно само все сохраняется в базу данных. Я намеренно скрыл реализацию базы данных, чтобы можно было подключать разные драйверы для разных баз данных. База данных должна быть лишь под капотом, и учавствовать лишь в сохранении состояния инстансов, а как она это будет делать, программиста пользователя, не должно волновать. В этом и суть этого фреймворка =) Перевод документации: ORMjs это javascript ООП интерфейс для базы данных. Он использует ArangoDB, но в будущем я добавлю драйверы для других баз (таких как mongodb) Концепция: Используя ES6 оператор await, геттеры и промисы, мы можем ассинхронно совершать навигацию по дереву графов документов в базе данных. Оно рекомендуется с использованием ES6, но вы так же можете писать на ES5 Я думаю что это эпично =) Это крайне крайне крайне крайне крайне элегантное API для работы с базой данных. А что вы думаете об этом? Она использует ArangoDB https://www.arangodb.com/2015/10/ben...godb-arangodb/ По ссылке тест производительности с другими базами данных типа Mongo. API static: Model.get(_id) // получает модель по id Model.add(obj) // создает модель на основе переданного обьекта Model.remove(model) // удаляет модель Model.restore(model) // восстанавливает удаленую модель Model.save(model) // сохраняет изменения модели в базу данных Model.update(model) // загружает состояние модели из базы данных instance Model.prototype.save() // псевдоним для Model.save(this) Model.prototype.update() // псевдоним для Model.update(this) Model.prototype.remove() // псевдоним для Model.remove(this) Model.prototype.restore() // псевдоним для Model.remove(this) Основы Определим коллекцию User (именем коллекции станет имя класса) let Model = require('ormjs') class User extends Model { static schema = { // базовые типы name: String, male: Boolean, age: Number, birth: Date, tags: Set, // как массив, только с уникальными элементами status: ['sleep', 'eat'], // enum (значением поля может быть одно из перечисленных значений) // структуры messages: [String], // массив строк prop1: {prop2: [{tags: [String]}] }, // можно описывать сколь угодно сложные вложенные структуры // ссылки на сущности из других коллекций (ну или этой же) bestFriend: User, // ссылка на инстанс User friends: [User], // ссылка на массив инстансов User // опции поля name: String, name: {$type: String}, name: {$type: String, test: /^\w+$/}, } } Example 0: let Model = require('ormjs') class User extends Model { static schema = { name: String, age: Number, } } Usage: (async function () { // adding user to db let user = await User.add({ name: 'Ашот', age: 24, }) user._id // 'User/434370324723' user._removed // false user.name // 'Ашот' user.age // 24 // change field user.name = 'Ololo' console.log(user.name) // 'Ololo' field is changed // reset changes await user.update() // load state from db user.name // 'Ашот' // saving changes user.name = 'Ololo' // change field await user.save() // save changes to db await user.update() // load state from db user.name // 'Ololo' because we save }()) Example 1: let Model = require('ormjs') class User extends Model { static schema = { name: String, age: Number, friends: [User] } async addFriend(user) { let friends = await this.friends friends.push(user) await this.save() } async removeAllFriends(){ this.friends = [] await this.save() } } Usage: (async function(){ let user = await User.add({ name: 'Ivan', age: 24, friends: [] }) await user.addFriend(user) await user.addFriend(user) await user.friends // [user, user] two itself =) await user.removeAllFriends() await user.friends // [] await user.friends === await user.friends // true user.name = 22 await user.save() // ValidationError: Field `name` must be String, but have Number })() Example 2: let Model = require('ormjs') class Sector extends Model { static schema = { size: Number } } class User extends Model { static schema = { name: String, sector: Sector, } } Usage: (async function () { let sector = await Sector.add({ size: 236 }) let user = await User.add({ name: 'Ашот', sector: sector }) (await user.sector).size // 236 let sector2 = await Sector.add({ size: 1004 }) user.sector = sector2 await user.save() (await user.sector).size // 1004 because this another sector ^__^ })() Custom types: System types is: String, Number, Boolean, Data, Set Actually we can use custom types: let Model = require('ormjs') class Color { constructor(r, g, b) { this.r = r this.g = g this.b = b } // convert to db document toJSON() { return { r: this.r, g: this.g, b: this.b } } // restore from db document static fromJSON(json) { return new Color(json.r, json.g, json.b) } } class User extends Model { static schema = { name: String, color: Color } } Usage: (async function () { let user = await User.add({ name: 'Ашот', color: new Color(0, 255, 0) }) user.color instanceof Color //true }()) Schemas Number schema = { age: Number, age: {$type: Number}, age: {$type: Number, min:0, max:100} } String schema = { name: String, name: {$type: String}, name: {$type: String, min:3, max:20, test:/^\w+$/} } Set schema = { tags: Set, tags: {$type: Set}, tags: {$type: Set, set: ['animals', 'porn', 'movie']} } Enum (for any type) Field value must be one of from enum array schema = { status: ['pending', 'resolve', 'reject'] } Это часть большого проекта, но я выгрузил её как отдельный модуль NPM, возможно она будет кому-то полезна. https://github.com/uMaxmaxmaximus/ui...erver/core/orm Напишите кто нибудь статью на хабре, кто умеет писать на хабре =) |
Лол, ты же плевался с ES6) Изменил мнение?
И да, async/await - это уже ES7. |
Цитата:
Ну было дело, ну ошибался я, и про кофескрипт ошибался, ну я просто думал что вы все врете и хотите мне плохое посоветовать и зла желаете. И сами мучаетесь и хотите меня мучать. На самом деле я по прежнему ненавижу ES синтаксис и у меня в списке TODO 3 технических проэкта на ближайшие 2 года 1) MegaJS (это такой изоморфный фреймворк на базе UIjs (плюс позволит писать и под десктопы и мобилки как React Native)) 2) CoffeeScript ES6 3) Аналог THREE с физикой (на Rust компилируемый в asm.js и wasm) На самом деле эту ORM я написал за неделю, а там писать особо и нечего, потестируйте кто нить. Никогда в подобных ORM не хватало такой вот удобной ссылки на другую коллекцию let frields = await user.frields. А вообще я поражаюсь как Babel написали стейт машину для ассинхронки. Это верх элеганства. Я бы не додумался, при том каллбак выполняется в том же конетксте следовательно сохраняются общие ппеременные и общий скоуп. Это феноминально. Щас я короч пишу такой же прозрачный API для этой бд но на клиенте, чтобы можно было такой же код писать, типа дай юзера, дай его друзей и.т.п. но при том чтобы проходили разные валидации на то к каким полям человек имеет доступ а к каким нет, что может модифицировать а что нет, то есть плитику прав доступа делаю. Чтобы больше не пистаь на клиенте api.getUsers() а писать как будто бы у нас база данных прям в браузере есть. Ну как в Meteor ============== Ребят ну активнее активнее, пожалуйста =) ![]() |
Ну ребята, я даже доку написал, все как вы просили, ну скачайте кто нибудь, протестируйте ну. Ну 0 даунлоадов за сутки ну...
![]() |
Будет custom validation и populate как в mongoose? Можно писать на генераторах с подключенной библиотекой co вместо async/await?
|
ORMjs, ты серьезно на гитхаб закинул после babel?
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Но вообще предполагается что валидация должна делаться на уровне модели. То есть у неё есть методы типа addUser removeMessages и они уже валидируют параметры передаваемые в них и как то сейвят состояние. Максимум что должно быть на слое ORM это как бы длинна данных (чтобы память не жрала 10000к строка например) и какие-то вещи связанные с длинной данных в базе данных и типом, а корректность данных, с точки зрения приложения, должна проверяться самими моделями и прогарммистом отдельно. То есть валидация это уже уровень ИСПОЛЬЗОВАНИЯ ORM а не внутри ORM. Но для удобства я щас добавлю функции $test |
Цитата:
|
Ну а кто вообще пишет на es6 и es7 без Babel? К тому же await это просто сахар на промисы, так что ограничений тут нет =)
(В typescript кстати await например есть) |
Часовой пояс GMT +3, время: 11:05. |
|