Giter Club home page Giter Club logo

db-connect's Introduction

db-connect

โš ๏ธ This was an experimental project and is not supported.

Connect your SQL database to Cloudflare Workers. Import this lightweight Javascript library to execute commands or cache queries from a database through an Argo Tunnel. Although designed for Workers, this library can be used in any environment that has access to the Fetch and SubtleCrypto APIs.

Installation

npm i -s @cloudflare/db-connect

Example

import { DbConnect } from '@cloudflare/db-connect'

const db = new DbConnect({
  host: 'sql.mysite.com', // Hostname of an Argo Tunnel
  clientId: 'xxx', // Client ID of an Access service token
  clientSecret: 'xxx' // Client Secret of an Access service token
})

async function findBirthday(name) {
  const resp = await db.submit({
    statement: 'SELECT * FROM users WHERE name = ? LIMIT 1',
    arguments: [ name ],
    cacheTtl: 60
  })

  if(!resp.ok) {
    return new Error('oops! could not find user.')
  }

  const users = await resp.json()
  // [ { "id": 1111,
  //   "name": "Matthew",
  //   "birthday": "2009-07-01" } ]

  return users[0].birthday
}

findBirthday('Matthew').then(bday => console.log(bday))

Quickstart

db-connect requires that you setup Cloudflare Access, Argo Tunnel, and Workers. You can use the quickstart command below or read the quickstart file for details on how to set this up yourself.

npm i -g @cloudflare/db-connect
db-connect-quickstart

Databases

db-connect supports the following database drivers out-of-the-box. If your database is not explicitly on the list it may still be supported. For instance, MariaDB uses the MySQL protocol and CockroachDB uses the PostgreSQL protocol.

Documentation

new DbConnect(options)

import { DbConnect } from '@cloudflare/db-connect'

const db = new DbConnect({
  host,         // required, hostname of your Argo Tunnel running in db-connect mode.
  clientId,     // recommended, client id from your Access service token.
  clientSecret, // recommended, client secret from your Access service token.
})

Promise<Response> db.ping()

import { DbConnect } from '@cloudflare/db-connect'

const db = new DbConnect({...})

async function myPing() {
  const resp = await db.ping()
  if(resp.ok) {
    return true
  }
  throw new Error(await resp.text())
}

new Command(options)

import { Command } from '@cloudflare/db-connect'

const cmd = new Command({
  statement, // required, the database statement to submit.
  arguments, // optional, either an array or object of arguments.
  mode,      // optional, type of command as either 'query' or 'exec'.
  isolation, // optional, type of transaction isolation, defaults to 'none' for no transactions.
  timeout,   // optional, number of seconds before a timeout, defaults to infinite.
  cacheTtl,  // optional, number of seconds to cache responses, defaults to -1.
  staleTtl,  // optional, after cacheTtl expires, number of seconds to serve stale, defaults to -1.
})

Promise<Response> db.submit(command)

import { DbConnect, Command } from '@cloudflare/db-connect'

const db = new DbConnect({...})

const cmd = new Command({
  statement: 'SELECT COUNT(*) AS n FROM books',
  cacheTtl: 60
})

async function mySubmit() {
  const resp = await db.submit(cmd)
  if(resp.ok) {
    return await resp.json() // [ { "n": 1234 } ]
  }
  throw new Error(await resp.text())
}

Testing

If you want to test db-connect without a database you can use the following command to create an in-memory SQLite3 database:

cloudflared db-connect --playground

db-connect's People

Contributors

electroid avatar zackbloom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

db-connect's Issues

sql column types are not respected

Currently in db-connect, column type is defined as a function argument, but the type is never used in coercion to JSON, and it instead guesses at the data type for every field.
This can lead to unexpected types in returned data where user input might be treated as something other than a string and break consuming code.
For example, in a database where I might expect typeof to resolve like

{
  "status": { "string": 9362 },
  "stats": { "object": 9362 }, // null or object
  "startedAt": { "string": 9362 }, // string (date)
  "sellerName": { "string": 9362 },
  "sellerCastle": { "string": 9362 },
  "quality": { "object": 8430, "string": 932 }, // null or string
  "price": { "number": 9362 },
  "lotId": { "string": 9362 }, // string, even if it looks like a number
  "itemName": { "string": 9362 }, // string (date)
  "finishedAt": { "string": 8692, "object": 670 }, // null or string (date)
  "endAt": { "string": 9362 }, // string (date)
  "condition": { "object": 8418, "string": 944 }, // null or string
  "buyerName": { "string": 7461, "object": 1901 }, // null or string
  "buyerCastle": { "string": 8194, "object": 1168 } // null or string
}

I instead see

{
  "status": { "string": 9362 },
  "stats": { "object": 9362 },
  "startedAt": { "string": 9362 },
  "sellerName": { "string": 9361, "number": 1 }, // user input string, parsing "8888" into 8888
  "sellerCastle": { "string": 9362 },
  "quality": { "object": 8430, "string": 932 },
  "price": { "number": 9362 },
  "lotId": { "number": 9362 }, // forward thinking to id changes, this is meant to be a string
  "itemName": { "string": 9362 },
  "finishedAt": { "string": 8692, "object": 670 },
  "endAt": { "string": 9362 },
  "condition": { "object": 8418, "string": 944 },
  "buyerName": { "string": 7461, "object": 1901 },
  "buyerCastle": { "string": 8194, "object": 1168 }
}

https://github.com/cloudflare/cloudflared/blob/710f66b0bbf9da94585235f6fba9b1a18ac631fa/dbconnect/sql.go#L278-L294

Remove Argo Tunnel requirement

No doubt this is already on the radar - but didn't see a distinct issue to track it.

As I understand it, the current Argo Tunnel requirement effectively means that db-connect can't be used with hosted databases such as Google SQL

Release with Argo Tunnel

Due to some outstanding deploy issues cloudflared db-connect is not yet available for customers. We are working on a fix!

Ongoing Support

This repo is marked as experimental, but the last update was a few months ago. Just curious if it is still being supported or there are future plans for it. Thanks!

Add npm publish to workflow pipeline

Edit the Github Action to npm publish after a successful build. This requires adding a NPM_TOKEN to the repository's secret vault under Settings.

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.