{"id":13719448,"url":"https://github.com/lspgn/edge-sql","last_synced_at":"2025-04-06T00:10:45.254Z","repository":{"id":42863607,"uuid":"319869564","full_name":"lspgn/edge-sql","owner":"lspgn","description":"Cloudflare Workers providing a SQL API","archived":false,"fork":false,"pushed_at":"2021-01-19T02:07:59.000Z","size":2442,"stargazers_count":557,"open_issues_count":0,"forks_count":19,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-03-29T23:11:11.473Z","etag":null,"topics":["cloudflare","cloudflare-workers","database","emscripten","forex","serverless","sql","sqlite3","wasm"],"latest_commit_sha":null,"homepage":"https://sql.lspgn.workers.dev/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lspgn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-09T06:55:52.000Z","updated_at":"2025-02-05T05:13:33.000Z","dependencies_parsed_at":"2022-07-09T06:30:16.828Z","dependency_job_id":null,"html_url":"https://github.com/lspgn/edge-sql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lspgn%2Fedge-sql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lspgn%2Fedge-sql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lspgn%2Fedge-sql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lspgn%2Fedge-sql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lspgn","download_url":"https://codeload.github.com/lspgn/edge-sql/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247415973,"owners_count":20935387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare","cloudflare-workers","database","emscripten","forex","serverless","sql","sqlite3","wasm"],"created_at":"2024-08-03T01:00:48.977Z","updated_at":"2025-04-06T00:10:45.238Z","avatar_url":"https://github.com/lspgn.png","language":"C","readme":"# edge-sql\n\n![Deploy](https://github.com/lspgn/edge-sql/workflows/Deploy/badge.svg)\n\nA [Cloudflare Worker](https://workers.cloudflare.com/) embedding [SQLite](https://sqlite.org/)\nwith [WASM](https://webassembly.org/) and a [simple Forex dataset](#data).\n\nYou can preview it here: [https://sql.lspgn.workers.dev](https://sql.lspgn.workers.dev).\n\n## Why?\n\n_I had an idea. Here's a little backstory._\n\nMany services provide a REST API on top of a SQL database.\nFor certain datasources, flexibility in terms of queries is key.\nOften those use-cases are dashboard prototyping, for example\nwith [Grafana](https://en.wikipedia.org/wiki/Grafana).\n\nThis data is usually read-only statistical datasets where the user\nneeds to run many queries in order to troubleshoot an issue\nor just find the best visualization.\nOften this requires complex queries and extensive accesses or quotas.\nUsing regular [REST APIs](https://en.wikipedia.org/wiki/Representational_state_transfer)\nwould require a lot of back-and-forth between the developers and the analysts.\nRecent initiatives like [GraphQL](https://en.wikipedia.org/wiki/GraphQL)\nare aimed at these issues and hope to provide more flexibility.\n\nThe idea behind this fun project is that serverless concepts can be applied for this use-case\nand have [SQL](https://en.wikipedia.org/wiki/SQL) as an execution model.\n[Foreign Data Wrappers](https://wiki.postgresql.org/wiki/Foreign_data_wrappers) are\nsimilar as they provide a framework that works with a Query Processor but \nneed to rely on more traditional user control and quotas configurations.\n\nCurrently, tools like [BigQuery](https://en.wikipedia.org/wiki/BigQuery)\nare used in [multi-tenancy environments](https://en.wikipedia.org/wiki/Multitenancy)\nand allow user to execute their SQL program without worrying about data infrastructure.\n\nThrough this fun prototype on the Cloudflare Workers platform,\nwe can put a sandbox around a SQL program and play with data\nstored in [Worker KVs](https://developers.cloudflare.com/workers/runtime-apis/kv).\n\nThe current setup is meant to use minimal resources ([Free limits](https://developers.cloudflare.com/workers/platform/limits)).\nThis is a proof of concept that was made possible by SQLite code that can fit inside the plateform (\u003c1MB).\nObviously, a rework of the code would be required to make it usable in a production\nenvironment. Features like sharding the data and the querying\nare necessary for large datasets, along with user control. The current quotas are controlled by the platform\nwhich can stop the execution of the entire Worker if it goes above the allowed limits.\n\n## Data\n\nThe data used in production is a reduced version (only EUR, JPY, GBP and CHF currencies) of the\n[European Central Bank Forex Rates on Humdata](https://data.humdata.org/dataset/ecb-fx-rates).\nAnd is [distributed](https://data.humdata.org/about/license) under the license\n[CC-BY](https://creativecommons.org/licenses/by/4.0/legalcode).\n\n## Try\n\nThe following query will return the days when the [British pound](https://en.wikipedia.org/wiki/Pound_sterling)\nwas at its lowest and highest against the dollar.\n\n```bash\n$ curl -XPOST --data \\\n\"\nSELECT *,1/EUR,1/JPY,1/GBP,1/CHF\nFROM forex\nWHERE\n  GBP = (\n    SELECT\n      max(GBP)\n    FROM forex)\n  OR GBP = (\n    SELECT\n      min(GBP)\n    FROM forex)\n\" \\\n-H 'content-type: application/text' \\\nhttps://sql.lspgn.workers.dev/\nDate,EUR,JPY,GBP,CHF,1/EUR,1/JPY,1/GBP,1/CHF\n2007-11-08,1.4666,0.008840265220012,2.10642728904847,0.883440756580929,0.681849174962498,113.118778126279,0.47473748806764,1.13193781535524\n```\n\n[Builtin SQLite functions](https://sqlite.org/lang_corefunc.html)\nalong with extra features are avaialble.\n\n```bash\n$ curl -XPOST --data \\\n\"\nSELECT\n  getdata('country') AS country,\n  random() AS rnd,\n  date('now') AS now\n\" \\\n-H 'content-type: application/text' \\\nhttps://sql.lspgn.workers.dev/\ncountry,rnd,now\nUS,-7348224717915799868,2021-01-18\n```\n","funding_links":[],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flspgn%2Fedge-sql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flspgn%2Fedge-sql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flspgn%2Fedge-sql/lists"}