2.2.10 • Published 6 months ago

pool-mysql v2.2.10

Weekly downloads
133
License
ISC
Repository
-
Last release
6 months ago

ReadME

Codacy Badge

npm.io

This is depend on mysql which made for migrating to features

  • multiple connection pool

  • connection writer/reader

  • async/await

  • model.query

  • log print

  • events

See the test Examples

Installation

  npm i pool-mysql --save

Usage

  • pool-mysql loads settings from process.env There is a helpful package dotenv
SQL_HOST={{writer}}
#reader is optional
SQL_HOST_READER={{reader}}
SQL_USER={{user}}
SQL_PASSWORD={{passwd}}
SQL_TABLE={{table name}}
  • Require pool-mysql
const pool = require('pool-mysql')

pool.query(sql, value, (err, data) => {

})
const options = {
  writer: {
    host: process.env.HOST2,
    database: process.env.DB2
  },
  reader: {
    host: process.env.HOST2,
    database: process.env.DB2
  },
  forceWriter: true
}

const pool2 = pool.createPool({ options })
const connection = pool.connection()

//callback query
connection.query(sql, values, (err,data) => {

})

//support async/await
try {
  const result = await connection.q(sql,value)
} catch(err) {
  console.log(err)
}
  • pool of connection pool

  • limit max connection amount with same priority

// if equal or more than 5 connections which tagged `foo`, wait for releasing
const connection = pool.connection({  limit: 5 })
// higher priority to get connection than 0
const connection = pool.connection({ priority: 1 })
const Schema = require('pool-mysql').Schema

const Posts = class posts extends Schema {
  get columns() {
    return {
      id: Schema.Types.PK,
      user: require('./user') // one to one reference
      //or
      user2: {
        ref: require('./user'), // one to one reference
        column: 'user'
      },

      user3: {
        type: Schema.Types.FK(require('./User.js'), 'id'),
        required: true,
        length: { min: 1, max: 20 },
      },

      user_type: {
        type: Schema.Types.ENUM('A','B','C')
      },

      available_area: {
        type: Schema.Types.Polygon
      },

      created_at: {
        type: Schema.Types.DateTime
      }
    }
}


const User = class user extends Schema {
  get columns() {
    return {
      id: Schema.Types.PK,
      user: [require('./posts')] //one to many reference
    }
}
await Posts
      .SELECT()         //default to columns()
      .FROM()
      .WHERE({id: 3})    //or you can use .WHERE('id = ?',3)
      .POPULATE('user') //query reference
      .PRINT()            //print sql statement, query time, connection id and works on writer/reader
      .WRITER           //force query on writer
      .exec()
// nest populate
const result = await Drivers
    .SELECT()
    .FROM()
    .WHERE({ driver_id: 3925 })
    .POPULATE({ trip_id: { driver_loc_FK_multiple: {} }})
    .FIRST()
    .exec()
const results = Trips.SELECT(Trips.KEYS, Users.KEYS)
    .FROM()
    .LEFTJOIN('user_info ON uid = trips.user_id')
    .WHERE('trip_id = ?', 23890)
    .AND('trip_id > 0')
    .LIMIT()
    .NESTTABLES()
    .MAP(result => {
        const trip = result.trips
        trip.user = result.user_info
        return trip
    })
    .FIRST()
    .exec()

results.should.have.property('trip_id')
results.trip_id.should.equal(23890)
results.should.have.property('user_id')
results.should.have.property('user')
results.user.should.have.property('uid')
assert(results instanceof Trips)

for massive rows query

  • Replace exec() with stream()
  • Some modifier will not works

  • highWaterMark

    • set to 1 : onValue.rows will be object
    • set to 2 or greater : onValue.rows will be array
      • rows.length will less or equal to highWaterMark
TableA
  .SELECT()
  .FROM()
  .LEFTJOIN('tableB on tableB.id = tableA.id')
  .LIMIT(25)
  .NESTTABLES()
  .MAP(data => {
    const tableA = data.tableA
    return { ...tableA, user: data.tableB }
  })
  .stream({
    connection, //optional
    highWaterMark: 5, //optional, default to 1
    onValue: (rows, done) => {
      assert.equal(rows.length, 5)
      expect(rows[0]).haveOwnProperty('id')
      expect(rows[0]).haveOwnProperty('user')

      done()
    },
    onEnd: (error) => {
      ok()
    }
  })

async / await

  • done will be a empty function
.stream({
  connection, //optional
  highWaterMark: 1, // if set to 1, will be object in `onValue`
  onValue: async (row,done) => {
    await doSomething()
  },
  onEnd: async (error) => {
    ok()
  }
})
// single
await FOO.INSERT()
  .INTO()
  .SET(obj)
  .exec(connection)

// multiple
await FOO.INSERT()
  .INTO('table (`id`, `some_one_field`)')
  .VALUES(array)
  .exec(connection)
  • return value after updated
const results = await Block
        .UPDATE()
        .SET('id = id')
        .WHERE({ blocked: 3925 })
        .UPDATED('id', 'blocker')
        .AFFECTED_ROWS(1) //throw if affectedRows !== 1
        .CHANGED_ROWS(1)  //throw if changedRows !== 1
        .ON_ERR('error message') // custom error message, can be string or callback
        .exec()

for (const result of results) {
    result.should.have.property('id')
    result.should.have.property('blocker')
}
const redis = require('redis')
const bluebird = require('bluebird')
bluebird.promisifyAll(redis.RedisClient.prototype)
bluebird.promisifyAll(redis.Multi.prototype)

const client = redis.createClient({
  host: ...,
  port: ...,
  db: ...
})

pool.redisClient = Redis

//...

const connection = pool.connection

await connection.q('SELECT id FROM user WHERE uid = ?', userID, {
  key: `api:user:id:${userID}`, //optional , default to queryString
  EX: process.env.NODE_ENV == 'production' ? 240 : 12, //default to 0 , it's required if need cache
  isJSON: true, //default to true
})

await connection.q('SELECT id FROM user WHERE uid = ?', userID, { EX: 60})

User.SELECT().FROM().WHERE('uid = ?',id).EX(60, { forceUpdate: true }).exec()
await Trips.UPDATE('user_info')
    .SET({ user_id: 31 })
    .WHERE({ uid: 31 })
    .CHANGED_ROWS(1)
    .ON_ERR(errMessage) // string
    .exec()
// or callback
await Trips.UPDATE('user_info')
    .SET({ user_id: 31 })
    .WHERE({ uid: 31 })
    .CHANGED_ROWS(1)
    .ON_ERR(err => {
        return 'error value'
    })
    .exec()
  • mass queries in the same time, combined queries will query once only (scope in instance)
Trips.SELECT().FROM().WHERE({ trip_id:1 }).COMBINE().exec().then().catch()
Trips.SELECT().FROM().WHERE({ trip_id:1 }).COMBINE().exec().then().catch()
Trips.SELECT().FROM().WHERE({ trip_id:1 }).COMBINE().exec().then().catch()
Trips.SELECT().FROM().WHERE({ trip_id:1 }).COMBINE().exec().then().catch()
// the second ... latest query will wait result from first one
  • Every 300 seconds free half reader&writer connections

  • But will keep at least 10 reader&writer connections

  • log logs not suggested to subscribe

  • get called when connection got from pool

  • create called when connection created

  • release called when connection released

  • will_query

  • query called when connection query

  • did_query

  • amount called when connection pool changes amount

  • end called when connection end

  • request request a connection but capped on connection limit

  • recycle free connection is back

  • warn warning

  • err error

pool.event.on('get', connection => {
    console.log(connection.id)
})
  • Triggered on UPDATE()..SET(object) and INSERT()...SET(object)

  • values must be object

default types

Variables

  • type: to limit type

  • required: default to false

    • INSERT() checks all required
    • UPDATE() checks SET()
  • length: limit something.length

// Custom Validator
class PlateNumber extends Scheme.Types.Base {
  static validate(string) {
    return string.match(/[0-9]+-[A-Z]+/)
  }
}

module.exports = class driver_review_status extends Scheme {

  get columns() {
    return {
      'uid': {
        type: Scheme.Types.PK,
        required: true
      },
      'first_name': {
        type: Scheme.Types.String,
        required: true,
      },
      'last_name': String,
      'car_brand': {
        type: Scheme.Types.JSONString
      },
      'model': {
        type: String
      },
      'phone_number': {
        type: Scheme.Types.String,
        required: true,
        length: 10
      },
      'plate_number': {
        type: PlateNumber,
        length: { min: 6 , max: 9 }
      },
      'email': {
        type: Scheme.Types.Email,
        required: true
      }
    }
  }
}
  • Usage

  • every query return response from mock() and increase index

  • assign mock() to pool will reset index to 0

  • rollback after execute
await Table.INSERT().INTO().rollback()
  • all print logs anywhere

  • error print logs if error

  • none never print logs

default to error

pool.logger = 'error'
// [3] Reader 1ms:  SELECT * FROM table

Custom Logger

pool._logger = (err, toPrint) => { }
2.2.10

6 months ago

2.2.7

2 years ago

2.2.9

2 years ago

2.2.8

2 years ago

2.2.5

2 years ago

2.2.6

2 years ago

2.2.4

3 years ago

2.2.3

3 years ago

2.2.2

3 years ago

2.2.1

3 years ago

2.2.0

3 years ago

2.2.0-0

3 years ago

2.1.2

3 years ago

2.1.1

3 years ago

2.1.0

3 years ago

2.0.4

3 years ago

2.0.4-0

3 years ago

2.0.3

3 years ago

2.0.3-2

3 years ago

2.0.3-1

3 years ago

2.0.3-0

3 years ago

2.0.2

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.7.15

3 years ago

1.7.14

3 years ago

1.7.13

3 years ago

1.7.11

3 years ago

1.7.12

3 years ago

1.7.10

3 years ago

1.7.8

3 years ago

1.7.7

3 years ago

1.7.6

4 years ago

1.7.5

4 years ago

1.7.4

4 years ago

1.7.3

4 years ago

1.7.2

4 years ago

1.7.1

4 years ago

1.7.0

4 years ago

1.6.0

4 years ago

1.5.22

4 years ago

1.5.21

4 years ago

1.5.20

4 years ago

1.5.19

4 years ago

1.5.18

4 years ago

1.5.17

4 years ago

1.5.16

4 years ago

1.5.15

4 years ago

1.5.14

4 years ago

1.5.13

4 years ago

1.5.12

4 years ago

1.5.11

4 years ago

1.5.9

4 years ago

1.5.10

4 years ago

1.5.8

4 years ago

1.5.7

4 years ago

1.5.6

4 years ago

1.5.5

4 years ago

1.5.4

4 years ago

1.5.3

4 years ago

1.5.2

4 years ago

1.5.1

4 years ago

1.5.0

4 years ago

1.4.21

4 years ago

1.4.20

4 years ago

1.4.19

4 years ago

1.4.18

5 years ago

1.4.17

5 years ago

1.4.16

5 years ago

1.4.15

5 years ago

1.4.14

5 years ago

1.4.13

5 years ago

1.4.12

5 years ago

1.4.11

5 years ago

1.4.10

5 years ago

1.4.9

5 years ago

1.1.4-7.1

5 years ago

1.4.8

5 years ago

1.4.7

5 years ago

1.4.6

5 years ago

1.4.5

5 years ago

1.4.4

5 years ago

1.4.3

5 years ago

1.4.2

5 years ago

1.4.1

5 years ago

1.4.0

5 years ago

1.3.16

5 years ago

1.3.15

5 years ago

1.3.13

5 years ago

1.3.12

5 years ago

1.3.11

5 years ago

1.3.10

5 years ago

1.3.9

5 years ago

1.3.8

5 years ago

1.3.7

5 years ago

1.3.6

5 years ago

1.3.5

5 years ago

1.3.4

5 years ago

1.3.3

5 years ago

1.3.2

5 years ago

1.3.1

5 years ago

1.3.0

6 years ago

1.1.68

6 years ago

1.1.67

6 years ago

1.1.66

6 years ago

1.1.65

6 years ago

1.1.64

6 years ago

1.1.5-6.2

6 years ago

1.1.63

6 years ago

1.1.62

6 years ago

1.1.61

6 years ago

1.1.60

6 years ago

1.1.59

6 years ago

1.1.58

6 years ago

1.1.57

6 years ago

1.1.56

6 years ago

1.1.55

6 years ago

1.1.54

6 years ago

1.1.53

6 years ago

1.1.52

6 years ago

1.1.51

6 years ago

1.1.50

6 years ago

1.1.47

6 years ago

1.1.46

6 years ago

1.1.45

6 years ago

1.1.44

6 years ago

1.1.43

6 years ago

1.1.42

6 years ago

1.1.41

6 years ago

1.1.40

6 years ago

1.1.38

6 years ago

1.1.37

6 years ago

1.1.36

6 years ago

1.1.35

6 years ago

1.1.34

6 years ago

1.1.33

6 years ago

1.1.32

6 years ago

1.1.31

6 years ago

1.1.30

6 years ago

1.2.13

6 years ago

1.2.12

6 years ago

1.2.11

6 years ago

1.2.10

6 years ago

1.1.29

6 years ago

1.1.28

6 years ago

1.1.27

6 years ago

1.1.26

6 years ago

1.1.25

7 years ago

1.2.4

7 years ago

1.2.3

7 years ago

1.2.2

7 years ago

1.2.1

7 years ago

1.2.0

7 years ago

1.1.23

7 years ago

1.1.22

7 years ago

1.1.21

7 years ago

1.1.20

7 years ago

1.1.19

7 years ago

1.1.18

7 years ago

1.1.17

7 years ago

1.1.16

7 years ago

1.1.15

7 years ago

1.1.14

7 years ago

1.1.13

7 years ago

1.1.12

7 years ago

1.1.11

7 years ago

1.1.10

7 years ago

1.1.9

7 years ago

1.1.8

7 years ago

1.1.7

7 years ago

1.1.6

7 years ago

1.1.5

7 years ago

1.1.3

7 years ago

1.1.2

7 years ago

1.1.1

7 years ago

1.1.0

7 years ago

1.0.7

7 years ago

1.0.6

7 years ago

1.0.5

7 years ago

1.0.4

7 years ago

1.0.3

7 years ago

1.0.2

7 years ago

1.0.1

7 years ago

1.0.0

7 years ago