GithubHelp home page GithubHelp logo

oknoah / final-orm Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 0.0 23.46 MB

Now witness my Final ORM! Node ORM for ArangoDB. Moved: https://gitlab.com/NoahGray/final-orm

Home Page: https://gitlab.com/NoahGray/final-orm

JavaScript 100.00%

final-orm's Introduction

Final ORM

Please check out https://github.com/oknoah/final and https://github.com/oknoah/final/packages/arangolize for similar projects that MAY be more up to date

This is a javascript OOP interface for ArangoDB

Conception: Using the ES7 operator await, getters and promises, we can navigate the graph objects tree.

It is recommended for use with the ES7 (async await) For a more beautiful syntax.

Never heard of ArangoDB? Check out these benchmarks: https://www.arangodb.com/2015/10/benchmark-postgresql-mongodb-arangodb/

Please see ./index.test.js for most up-to-date examples.

API

static:

Model.get(_id) // get model by id
Model.add(obj) // add model by description obj
Model.remove(model) // remove model
Model.restore(model) // restore removed model
Model.save(model) // save modified model to db
Model.update(model) // update modified model from db
Model.find({ where: { key: value }, skip: 0, limit: 10 }) // find models by where obj
Model.findAndCount({ where: { key: value }, skip: 0, limit: 10 }) // find models by where obj and return as { data: [data], meta: { count: 123 } }
Model.findOne({ where: { key: value } }) // find one model by selector obj
Model.count(selector) // return count models matches of selector
Model.have(selector) // returns true if there is at least one model suitable for selector

instance:

Model.prototype.save() // alias  Model.save(this)
Model.prototype.update() // alias  Model.update(this)
Model.prototype.remove() // alias  Model.remove(this)
Model.prototype.restore() // alias  Model.remove(this)

Basic usage:

create init class model.js

var orm = require('final-orm')
var options = {
  database: 'test', // db name
  // You can initialize the database using a url.
  url: 'http://root:@localhost:8529',
  // Or supply each of these values. You do not need both.
  host: 'localhost',
  port: '8529',
  username: 'root',
  password: ''
}

var { Model, Edge } = orm.connect(options)

export default Model

export { Model, Edge }

orm.connect() returns Model and Edge classes, and you need export and extend it

Define collection User (class name will be collection name), and edge collection "Like"

import { Model, Edge } from './model.js'

class User extends Model {
  static schema = {
    // basic types
    name: String,
    male: Boolean,
    age: Number,
    birth: Date,
    tags: Set, // like array but items are unique

    // structures
    messages: [String], // array of types
    prop1: {prop2: [{tags: [String]}] }, // sub schemas

    // relations with other (or self) db collections
    bestFriend: User, // link to model
    friends: [User], // link to array models

    // field options
    name: String,
    name: {$type: String},
    name: {$type: String, test: /^\w+$/},
    status: {
      $type: String,
      enum: ['sleep', 'eat'], // enum
      optional: true // allows null value
    }
  }
}

class Like extends Edge {
  static schema = {
    date: Date
  }
}

Example 0:

import Model from './model.js'


class User extends Model {

  static schema = {
    name: String,
    age: Number,
  }

}

Usage:

(async function () {

  // adding user to db
  var 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

  // like via edge collection
  const rose = await User.findOne({ where: { name: 'Rose' } })
  // in edge collections, the usage is Edge.add(from, to, data)
  Like.add(rose, user, { date: new Date() })

}())

Example 1: Instance methods

import Model from './model.js'


class User extends Model {
  static schema = {
    name: String,
    age: Number,
    friends: [User]
  }

  async addFriend(user) {
    var friends = await this.friends
    friends.push(user)
    await this.save()
  }

  async removeAllFriends(){
    this.friends = []
    await this.save()
  }

}

Usage:

(async function(){

  var 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

  await user.removeAllFriends() // since this method uses this.update, you must do user.save() first

})()

Example 2:

import Model from './model.js'


class Sector extends Model {

  static schema = {
    size: Number
  }

}


class User extends Model {

  static schema = {
    name: String,
    sector: Sector,
  }

}

Usage:

(async function () {

  var sector = await Sector.add({
    size: 236
  })

  var user = await User.add({
    name: 'Ашот',
    sector: sector
  })

  (await user.sector).size // 236


  var 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:

import Model from './model.js'


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 () {

  var 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: ['soviet', 'movies']}
}

final-orm's People

Contributors

oknoah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

final-orm's Issues

Add support for defaults

export default class User extends Model {
  static schema = {
    name: String,
    email: String,
    password: String,
    role: { $type: String, enum: ['ADMIN', 'USER'], default: 'USER' },

Also, perhaps there needs to be some consistency with the naming of options. $ before or not?

Cannot set indexes

This code does not seem to work as intended:

static async _getCollection () {
    if (this._collection) {  // always seems to be true
      return this._collection
    }

    const db = await this._getDatabase()
    const collection = db.collection(this.name)
    try {
      await collection.create()
      await this._setIndexes(collection)
    } catch (e) {
    }
    return this._collection = collection
  }

  static async _setIndexes (collection) {
    const schema = this._getSchema()
    for (const field of schema) {
      if (!field.options.index) continue

      const path = field.path.join('.')
      const unique = field.options.unique
      await collection.createHashIndex(path, {unique})
    }
  }

Map AQL to Argument

Hi,

I am using the following function:

User.findOne({where: {email: email, username: username}})

With this query, I get the first user which has the specified email AND username (if there is one), right? Is it also possible to specify that I want to get the first user who has the specified email OR username? If it's possible, what do I have to pass as parameter?

Thanks in advance!

Best regards,
Jinxcifer

Requesting MyModel._collection fails the first time

When doing

const collection = await MyModel._collection // returns null

it seems to always return null the first time. Running the function again will work properly. I guess it is not initialized full. Maybe a constructor is needed to fix this.

Hard Delete

Hi again!

I currently have the situation where I have a user ID and I want to delete that user from the database. I have the following two questions:

  1. To delete the user, I need to do the following:
const user = User.get(_id);
user.remove();

This will result in two database queries, right? Is there another way to do it in just one query, f.e. User.remove(_id);?

  1. When I use

Model.remove(model)

or

Model.prototype.remove()

it only changes the removed flag from false to true. Is there a way to hard delete the user from the database as well?

Thanks in advance!

Best regards,
jinxcifer

Error: getaddrinfo ENOTFOUND

When trying to connect to arangoDB with specified host (besides 'localhost'), it always return this error

Error: getaddrinfo ENOTFOUND user_name user_name:80

I already specified all information needed but it seemed override the configuration parameters I specified.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.