{"id":13994590,"url":"https://github.com/0x6b/libgsqlite","last_synced_at":"2025-07-22T19:32:56.874Z","repository":{"id":52146798,"uuid":"520804429","full_name":"0x6b/libgsqlite","owner":"0x6b","description":"A SQLite extension which loads a Google Sheet as a virtual table.","archived":false,"fork":true,"pushed_at":"2022-10-21T02:55:37.000Z","size":2410,"stargazers_count":511,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-10T14:16:32.953Z","etag":null,"topics":["rust","sqlite-extension"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"x2bool/xlite","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0x6b.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-08-03T08:49:18.000Z","updated_at":"2024-07-06T01:31:15.000Z","dependencies_parsed_at":"2023-01-20T06:41:04.406Z","dependency_job_id":null,"html_url":"https://github.com/0x6b/libgsqlite","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x6b%2Flibgsqlite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x6b%2Flibgsqlite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x6b%2Flibgsqlite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x6b%2Flibgsqlite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0x6b","download_url":"https://codeload.github.com/0x6b/libgsqlite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227166816,"owners_count":17740985,"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":["rust","sqlite-extension"],"created_at":"2024-08-09T14:02:57.973Z","updated_at":"2024-11-29T16:31:36.994Z","avatar_url":"https://github.com/0x6b.png","language":"Rust","funding_links":[],"categories":["Rust","Extensions","rust"],"sub_categories":[],"readme":"# libgsqlite\n\nA [SQLite](https://www.sqlite.org) extension which loads a [Google Sheet](https://www.google.com/sheets/about/) as a virtual table.\n\nhttps://user-images.githubusercontent.com/679719/182612984-3e1156c5-cc95-4450-bb20-2fd76f51aa3d.mp4\n\n## Tested Platform\n\n- [SQLite](https://www.sqlite.org) 3.39.2\n- [Rust](https://www.rust-lang.org) 1.62.1-aarch64-apple-darwin\n- macOS 12.5 (Monterey) on Apple M1 MAX\n\n## Getting Started\n\n### Setup Google Cloud\n\n#### Create a Project\n\n1. Log in to the [Google Cloud console](https://console.cloud.google.com/).\n2. Go to the [**Manage resources**](https://console.cloud.google.com/cloud-resource-manager) page.\n3. On the **Select organization** drop-down list at the top of the page, select the organization resource in which you want to create a project.\n4. Click **Create Project**.\n5. In the **New Project** window that appears, enter a project name, say `libgsqlite`, and select a billing account as applicable.\n6. Enter the parent organization or folder resource in the **Location** box.\n7. When you're finished entering new project details, click **Create**.\n\n#### Enable Google Sheets API for the Project\n\n1. Go to the [**API Library**](https://console.cloud.google.com/apis/library?project=_) page.\n2. From the projects list, select the project you just created.\n3. In the API Library, select **Google Sheets API**.\n4. On the API page, click **Enable**.\n\n#### Setup Google OAuth Consent Screen\n\n1. Go to the [**OAuth consent screen**](https://console.cloud.google.com/apis/credentials/consent) page.\n2. Select **Internal** as User Type, then click **Create**\n3. Add required information like an app name (`libgsqlite`) and support email address.\n4. Click **Save and Continue**.\n5. Click **Add or Remove Scopes**.\n6. On the dialog that appears, select the scope `.../auth/spreadsheets.readonly` (See all your Google Sheets spreadsheets) and click **Update**.\n7. Click **Save and Continue**.\n8. Click **Back to Dashboard**.\n\n#### Create a Credential\n\n1. Go to the [**Credentials**](https://console.cloud.google.com/apis/credentials) page.\n2. Click **Create Credentials** → **OAuth Client ID**.\n3. Select **Desktop app** as Application Type.\n4. Type `libgsqlite` as Name.\n5. Click **Download JSON** to save your **Client ID** and **Client Secret** locally.\n\n### Create a Sample Spreadsheet\n\n1. Go to [sheet.new](https://sheet.new) to create a new spreadsheet, then copy and paste following data.\n\n| Employee Number | First Name | Last Name | Department |\n|----------------:|------------|-----------|------------|\n|               1 | Christine  | Haas      | A00        |\n|               2 | Michael    | Thompson  | B01        |\n|               3 | Sally      | Kwan      | C01        |\n|               4 | John       | Beyer     | E01        |\n|               5 | Irving     | Stern     | D11        |\n|               6 | Eva        | Pulaski   | E01        |\n\n2. Copy the URL of the spreadsheet.\n\n### Query the Spreadsheet with SQLite\n\n1. Setup required environment variables with the credential:\n   ```shell\n   $ export LIBGSQLITE_GOOGLE_CLIENT_ID=... # client_id property in the downloaded JSON\n   $ export LIBGSQLITE_GOOGLE_CLIENT_SECRET=... # client_secret property\n   ```\n2. Launch SQLite:\n   ```shell\n   $ sqlite3\n   ```\n3. Load the extension:\n   ```shell\n   .load libgsqlite # or \"gsqlite\" on Windows\n   ```\n   If you get `Error: unknown command or invalid arguments: \"load\". Enter \".help\" for help `, your SQLite is not capable for loading an extension. For macOS, install it with `brew install sqlite3`, and use it.\n4. Create a virtual table for your spreadsheet by providing `ID` (url of the spreadsheet), `SHEET` (sheet name), and `RANGE` for module arguments. All three arguments are mandatory. You'll be navigated to Google OAuth consent screen to get a secret to access the spreadsheet. You can create multiple virtual tables from different spreadsheets.\n   ```sql\n   CREATE VIRTUAL TABLE employees USING gsqlite(\n       ID 'https://docs.google.com/spreadsheets/d/...', -- your spreadsheet URL\n       SHEET 'Sheet1', -- name of the sheet\n       RANGE 'A2:D7' -- range to fetch\n   );\n   ```\n5. Go back to your terminal, and run a query as usual:\n   ```sql\n   .mode column\n   .headers on\n   SELECT * FROM employees;\n   SELECT * FROM employees WHERE D LIKE 'E%';\n   ```\n\n# Contributing\n\nPlease read [CONTRIBUTING](CONTRIBUTING.md) for more detail.\n\n# Acknowledgements\n\nAn article, [Extending SQLite with Rust to support Excel files as virtual tables | Sergey Khabibullin](https://sergey.khabibullin.com/sqlite-extensions-in-rust/), and its companion repository [x2bool/xlite](https://github.com/x2bool/xlite), for great write up and inspiration.\n\n# Limitations\n\n- The extension will load the spreadsheet only once while creating a virtual table. If you want to pick up recent changes, drop the table and create it again.\n- `INSERT`, `UPDATE` and `DELETE` statements won't be implemented. Welcome PRs.\n\n# Security\n\nThe extension is intended for use in personal, not-shared, environment. The Google Cloud secret will be cached for 59 minutes under the temporary directory (See [`std::env::temp_dir`](https://doc.rust-lang.org/std/env/fn.temp_dir.html)) with fixed name `access_token.json` for your convenience. Note that, as described at the doc, creating a file or directory with a fixed or predictable name may result in “insecure temporary file” security vulnerability.\n\n# Privacy\n\nThe extension never send your data to any server.\n\n# License\n\nThis extension is released under the MIT License. See [LICENSE](LICENSE) for details.\n\n# References\n\n- [Quickstart: Manage your Google Cloud resources](https://cloud.google.com/resource-manager/docs/manage-google-cloud-resources#create_a_project_resource)\n- [Getting started | Cloud APIs](https://cloud.google.com/apis/docs/getting-started)\n- [Setting up OAuth 2.0](https://support.google.com/cloud/answer/6158849?hl=en\u0026ref_topic=3473162)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0x6b%2Flibgsqlite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0x6b%2Flibgsqlite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0x6b%2Flibgsqlite/lists"}