├── .gitignore ├── README.md ├── api └── country.js ├── ip2location.ipv4.sql ├── package.json └── public ├── favicon.ico └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | sqlite/ 3 | package-lock.json 4 | .vercel 5 | *.CSV 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vercel SQLite ip2location demo 2 | 3 | Photo by Elena Mozhvilo on Unsplash 4 | 5 | ## [Live Demo](https://vercel-sqlite-demo.vercel.app/) 6 | 7 | Wait for the `fetch('api/country')` to show where you come from. 8 | 9 | ## How to test 10 | 11 | * fork or clone this repository and go into its folder 12 | * download [IPV4 CSV](https://lite.ip2location.com/database/ip-country) 13 | * copy the unzipped `IP2LOCATION-LITE-DB1.CSV` file into the folder 14 | * create an `sqlite` directory (`mkdir -p sqlite`) and run `sqlite3 sqlite/ip2location.ipv4` 15 | * copy and paste [ip2location.ipv4.sql](./ip2location.ipv4.sql) content in the *SQLite* shell 16 | * run `npx vercel --prod` to deploy 17 | 18 | ## Please Note 19 | 20 | While having a static, read-only, *SQLite* database on *vercel* could be handy in various situations, you cannot upload more than *100MB* as deploy/build size in there, so be aware this technique might not scale. 21 | -------------------------------------------------------------------------------- /api/country.js: -------------------------------------------------------------------------------- 1 | const {join} = require('path'); 2 | const {now} = require('perf_hooks').performance; 3 | 4 | const {Database} = require('sqlite3'); 5 | const SQLiteTag = require('sqlite-tag'); 6 | 7 | const ip2location = join(__dirname, '..', 'sqlite', 'ip2location.ipv4'); 8 | 9 | const ipv4 = { 10 | _: [16777216, 65536, 256, 1], 11 | $: (whole, current, i) => (whole + current * ipv4._[i]), 12 | asInt: ip => ip.split('.').reduce(ipv4.$, 0), 13 | asRegExp: /^(?:\d+\.){3}\d+$/ 14 | }; 15 | 16 | module.exports = async (req, res) => { 17 | const address = req.headers['x-forwarded-for'] || req.connection.remoteAddress; 18 | if (ipv4.asRegExp.test(address)) { 19 | const time = now(); 20 | const db = new Database(ip2location); 21 | const {get} = SQLiteTag(db); 22 | const location = await get` 23 | SELECT 24 | country_code AS code, 25 | country_name AS name 26 | FROM 27 | ip2location 28 | WHERE 29 | ${ipv4.asInt(address)} 30 | BETWEEN ip_from AND ip_to 31 | `; 32 | db.close(); 33 | res.setHeader('x-served-in', `${(now() - time).toFixed(2)}ms`); 34 | res.json(location || {code: '❔', name: 'Unknown'}); 35 | } 36 | else 37 | res.json({code: '⚠', name: 'Invalid IP'}); 38 | }; 39 | -------------------------------------------------------------------------------- /ip2location.ipv4.sql: -------------------------------------------------------------------------------- 1 | -- mkdir -p sqlite 2 | -- sqlite3 sqlite/ip2location.ipv4 3 | 4 | CREATE TABLE ip2location ( 5 | ip_from INT(10), 6 | ip_to INT(10), 7 | country_code CHAR(2), 8 | country_name VARCHAR(64), 9 | PRIMARY KEY(ip_from, ip_to) 10 | ); 11 | 12 | -- https://lite.ip2location.com/database/ip-country 13 | .mode csv 14 | .import IP2LOCATION-LITE-DB1.CSV ip2location 15 | 16 | DELETE FROM ip2location WHERE country_code = "-"; 17 | 18 | -- SELECT country_code AS code, country_name AS name FROM ip2location WHERE 35977539 BETWEEN ip_from AND ip_to; 19 | 20 | .exit 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "vercel-sqlite-demo", 4 | "type": "commonjs", 5 | "description": "Vercel SQLite ip2location demo", 6 | "author": "Andrea Giammarchi", 7 | "license": "ISC", 8 | "dependencies": { 9 | "sqlite-tag": "^1.1.0", 10 | "sqlite3": "^5.0.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/vercel-sqlite-demo/0478decbe5ffee361c9aa27576d673a8978e5ca2/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vercel SQLite ip2location demo 8 | 17 | 22 | 23 | 24 |

Vercel SQLite ip2location demo

25 |

26 | This site or product includes IP2Location LITE data available from 27 | https://lite.ip2location.com. 28 |

29 |

30 | 31 | 32 | --------------------------------------------------------------------------------