npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rqlite-js

v2.5.7

Published

A client library for RQLite written in Javascript that works in NodeJS or the browser.

Downloads

500

Readme

rqlite-js · npm version · Build Status · Google Group

A promise based client library for rqlite, the lightweight, distributed database built on SQLite. This package is designed to provide javascript classes with interfaces that line up with RQLite API endpoints. Please note that there is no code in this package for writing SQL queries. There are other Javascript SQL generator libraries such as sequel which can be used to create the SQLite query strings. You are welcome to use one of those libraries or write your own SQL queries directly in your code.

Features

  • Automatically follow 301 redirects from replicates to leader node
  • Round robin load balancing of leader node and all replicate nodes for query api requests
  • HTTP Keepalive support through http and https agents when initializing clients or on individual requests see Client options
  • Unit and integration tests for contributors

DataApiClient

The data API client will allow you to access the data API endpoints of RQLite such as query and execute. All data methods will return a DataResults instance which is an array of DataResult instances. The DataResult instances are designed to abstract working with the response body from RQLite data endpoints. If you want to work with the raw HTTP response instead of using the DataResults the options accept a raw options which can be set to true. This is covered in the examples below.

DataApiClient Methods

The follow methods are available on the DataApiClient including their method signatures. Both the query and execute methods return a DataResults instance which provides methods for handling the RQLite response body states. In the case of a query there will only ever be one result in the DataResults.

  • DataApiClient.query(sql, options) - Single query SQL statments sent via HTTP get (Note, if you pass an array it will call execute internally)
  • DataApiClient.execute(sql, options) - Multiple SQL statments

DATA API Usage

CREATE TABLE Example

The code sample shows how you would connect to a rqlite server and create a table.

import { DataApiClient } from 'rqlite-js'

const dataApiClient = new DataApiClient('http://localhost:4001')
try {
  // You can create your own raw SQL query or use another SQL generator library of your liking.
  const sql = 'CREATE TABLE foo (id integer not null primary key, name text)'
  const dataResults = await dataApiClient.execute(sql)
  // Check the results for an error to make sure we the SQL query did
  // not generate an error while executing.
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite create tables results contained an error.')
    return
  }
  // We are successful and have results to use from our SQL query.
  console.log(dataResults.toString(), 'Checkout the rqlite results as a JSON string.')
  console.log(dataResults.toArray(), 'Checkout the rqlite results as plain javascript array for app use.')
  console.log(dataResults.get(0).toString(), 'Checkout just the first rqlite result as a JSON string.')

  // Lets get the same query as a raw HTTP response
  const { statusCode, body } = await dataApiClient.execute(sql, { raw: true })
  console.log(body, 'HTTP reponse body.')
  console.log(statusCode, 'HTTP response code.')
} catch (e) {
  console.error(e, 'The HTTP client got an HTTP error, there must be something else going on.')
}

Multiple QUERY Example

The code sample shows how would connect to a rqlite server insert a row then select the row.

import { DataApiClient } from 'rqlite-js'

const dataApiClient = new DataApiClient('http://localhost:4001')
try {
  // Insert a row into the table foo we create above in the CREATE TABLE example.
  // The values for sql can be a string or an array if you want to execute multiple
  // SQL queries on the server.
  let dataResults = await dataApiClient.execute('INSERT INTO foo(name) VALUES(\"fiona\")')
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite insert results contained an error.')
    return
  }
  const id = dataResults.get(0).getLastInsertId()
  console.log(id, 'The id of the inserted row')
  dataResults = await dataApiClient.query(`SELECT name FROM foo WHERE id="${id}"`)
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite select results contained an error.')
    return
  }
  console.log(dataResults.get(0).get('name'), 'The value for the name field which should equal fiona')
  console.log(dataResults.get(0).toObject(), 'rqlitejs results are great, but I just want to work with a plain js object maybe to send back in my api')
  console.log(dataResults.get(0).get('id'), 'This is just the id of the first result.')
  dataResults = await dataApiClient.execute(`UPDATE foo SET name="justin" WHERE name="fiona"`)
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite select results contained an error.')
    return
  }
  const rowsAffected = dataResults.get(0).getRowsAffected()
  console.log(rowsAffected, 'The number of rows updated for each update query which should be 1 for the first row')
  dataResults = await dataApiClient.query(`SELECT name FROM foo WHERE id="${id}"`)
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite select results contained an error.')
    return
  }
  console.log(dataResults.get(0).get('name'), 'The value for the name field which should now equal justin')
} catch (e) {
  console.error(e, 'The HTTP client got an HTTP error, there must be something else going on.')
}

Using transactions Example

The code sample shows how would connect to a rqlite and run multiple insert queries within a transaction transactions.

import { DataApiClient } from 'rqlite-js'

const dataApiClient = new DataApiClient('http://localhost:4001')
try {
  // Insert a row into the table foo we create above in the CREATE TABLE example.
  // The values for sql can be a string or an array if you want to execute multiple
  // SQL queries on the server.
  const sql = [
    'INSERT INTO foo(name) VALUES(\"fiona\")',
    'INSERT INTO bar(name) VALUES(\"test\")',
  ]
  const dataResults = await dataApiClient.execute(sql, { transaction: true })
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite insert results contained an error.')
    return
  }
  console.log(dataResults.get(0).getLastInsertId(), 'The id for the first insert is in index 0 last_insert_id')
  console.log(dataResults.get(1).getLastInsertId(), 'The id for the second insert is in index 1 last_insert_id')
} catch (e) {
  console.error(e, 'The HTTP client got an HTTP error, there must be something else going on.')
}

Multiple QUERY Example With Consistency

The code sample shows how would connect to a rqlite and run multiple select queries with strong consistency.

import { DataApiClient } from 'rqlite-js'

const dataApiClient = new DataApiClient('http://localhost:4001')
try {
  const sql = [
    'SELECT name FROM foo WHERE id="1"',
    'SELECT id FROM bar WHERE name="test"',
  ]
  const dataResults = await dataApiClient.query(sql, { level: 'strong' })
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite insert results contained an error.')
    return
  }
  console.log(dataResults.get(0).toString(), 'The results for the first select are in index 0')
  console.log(dataResults.get(1).toString(), 'The results for the second select are in index 1')
} catch (e) {
  console.error(e, 'The HTTP client got an HTTP error, there must be something else going on.')
}

Authentication

Authentication can be set using the authentication property on the DataApiClient options.

import { DataApiClient } from 'rqlite-js'

const username = 'rqliteUsername'
const password = 'rqlitePassword'
const dataApiClient = new DataApiClient('http://localhost:4001', {
  authentication: { username, password },
})
try {
  const sql = [
    'SELECT name FROM foo WHERE id="1"',
    'SELECT id FROM bar WHERE name="test"',
  ]
  const dataResults = await dataApiClient.query(sql, { level: 'strong' })
  if (dataResults.hasError()) {
    const error = dataResults.getFirstError()
    console.error(error, 'rqlite insert results contained an error.')
    return
  }
  console.log(dataResults.get(0).toString(), 'The results for the first select are in index 0')
  console.log(dataResults.get(1).toString(), 'The results for the second select are in index 1')
} catch (e) {
  console.error(e, 'The HTTP client got an HTTP error, there must be something else going on.')
}

Client options

Multiple hosts can be provided using the construtor for the data api client. For greater performance when making http requests it is often useful to provide an http and https agent to the client through options.

import { DataApiClient } from 'rqlite-js'
import http from 'http'
import https from 'https'

// Hosts can be an array or a string that is comma seperated e.g. 'http://localhost:4001,http://localhost:4002,http://localhost:4003'
const dataApiClient = new DataApiClient(['http://localhost:4001', 'http://localhost:4002', 'http://localhost:4003'], {
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),
})

Retrys

All http requests are retried with exponential backoff up to the number of hosts times 3. Each retry tries the next host in the rotation. To see the http status codes, error codes and http methods which cause a retry have a look at es6/http-request/retryable.js. When creating an instance you can supply your own Set or Array of replacement values. To manually disable all retry logic provide the contructor an entries properties with the value 0.

import { DataApiClient } from 'rqlite-js'
import http from 'http'
import https from 'https'

// Hosts can be an array or a string that is comma seperated e.g. 'http://localhost:4001,http://localhost:4002,http://localhost:4003'
const dataApiClient = new DataApiClient(['http://localhost:4001', 'http://localhost:4002', 'http://localhost:4003'], {
  retryableErrorCodes: Set([600]), // Retry HTTP response status code 600
  retryableStatusCodes: Set(['SPECIAL_ERROR_CODE']), // Retry error.code === SPECIAL_ERROR_CODE
  retryableHttpMethods: Set(['GET']), // Only retry GET requests
  retries: 0, // Manually disable all retry logic
})

Testing

Please see the docs/test/README.md for more information on testing for use by contributors.