From f0055ecf2a8918512bca594bca0c05e21b8e1866 Mon Sep 17 00:00:00 2001 From: oof1lab Date: Tue, 31 Oct 2017 16:35:18 +0000 Subject: [PATCH] feature addition: file upload and downloads version: 0.0.5 --- README.md | 45 ++++++++++++++++++++++++++++++++ lib/util/cmd.helper.js | 8 ++++-- lib/xapi.js | 59 ++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 4 files changed, 111 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 498549123b..abd863c1f1 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,9 @@ That's it! * Group By, Order By * Relations * Run dynamic queries +* Upload single file +* Upload multiple files +* Download file Use HTTP clients like [Postman](https://www.getpostman.com/) or [similar tools](https://chrome.google.com/webstore/search/http%20client?_category=apps) to invoke REST API calls @@ -192,7 +195,31 @@ xmysql identifies foreign key relations automatically and provides GET api. ``` eg: Customers is parent table and payments is child table. API invocation will result in all payments with customer 103. +## Upload single file +``` +POST /upload +``` +eg: curl --form file=@/Users/me/Desktop/a.png http://localhost:3000/upload + +returns uploaded file name else 'upload failed' + +(Note: POSTMAN has issues with file uploading hence examples with curl) + +## Upload multiple files +``` +POST /uploads +``` +> Notice 's' near /api/upload**s** and file**s** in below example + +eg: curl --form files=@/Users/me/Desktop/a.png --form files=@/Users/me/Desktop/b.png http://localhost:3000/uploads + +returns uploaded file names as string + +## Download file +http://localhost:3000/download?name=fileName + +For upload and download of files -> you can specify storage folder using -s option ## When to use ? * You need just REST APIs without much hassle for (ANY) MySql database. @@ -204,6 +231,24 @@ eg: Customers is parent table and payments is child table. API invocation will r * Other times not mentioned in when to use section +### Command line options + +``` + Options: + + -V, --version output the version number + -h, --host hostname of mysql + -d, --database database schema name + -u, --user username of database / root by default + -p, --password password of database / empty by default + -n, --portNumber port number / 3000 by default + -s, --storageFolder storage folder / current working dir by default + -h, --help output usage information + + Examples: + + $ xmysql -u username -p password -d databaseSchema +``` diff --git a/lib/util/cmd.helper.js b/lib/util/cmd.helper.js index 61fefb845a..605411008d 100644 --- a/lib/util/cmd.helper.js +++ b/lib/util/cmd.helper.js @@ -11,12 +11,13 @@ program.on('--help', () => { }) program - .version('0.0.4') + .version('0.0.5') .option('-h, --host ', 'hostname') .option('-d, --database ', 'database schema name') .option('-u, --user ', 'username of database / root by default') .option('-p, --password ', 'password of database / empty by default') .option('-n, --portNumber ', 'port number : 3000 by default') + .option('-s, --storageFolder ', 'storage folder / current working dir by default') .parse(process.argv) @@ -49,6 +50,9 @@ exports.handle = program => { program.user = program.user || 'root'; program.password = program.password || ''; program.host = program.host || 'localhost'; + program.storageFolder = program.storageFolder || process.cwd() + + console.log('storage::', program.storageFolder); program.connectionLimit = 10; @@ -61,7 +65,7 @@ exports.handle = program => { if (program.database && program.host && program.user) { - console.log('Starting server at:', 'http://'+program.host + ':' + program.portNumber) + console.log('Starting server at:', 'http://' + program.host + ':' + program.portNumber) } else { processInvalidArguments(program) process.exit(1) diff --git a/lib/xapi.js b/lib/xapi.js index c17aa7e633..6ee7c94a9e 100644 --- a/lib/xapi.js +++ b/lib/xapi.js @@ -1,6 +1,8 @@ 'use strict'; var Xsql = require('./xsql.js'); +var multer = require('multer'); +var path = require('path'); //define class class Xapi { @@ -11,6 +13,21 @@ class Xapi { this.mysql = new Xsql(args, mysqlPool) this.app = app; + /**************** START : multer ****************/ + this.storage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, process.cwd()) + }, + filename: function (req, file, cb) { + console.log(file); + cb(null, Date.now() + '-' + file.originalname) + } + }) + + this.upload = multer({storage: this.storage}) + /**************** END : multer ****************/ + + } @@ -162,6 +179,14 @@ class Xapi { .post(this.asyncMiddleware(this.runQuery.bind(this))); } + + /**************** START : multer routes ****************/ + this.app.post('/upload', this.upload.single('file'), this.uploadFile.bind(this)); + this.app.post('/uploads', this.upload.array('files', 10), this.uploadFiles.bind(this)); + this.app.get('/download', this.downloadFile.bind(this)); + /**************** END : multer routes ****************/ + + } async create(req, res) { @@ -402,6 +427,40 @@ class Xapi { } + + /**************** START : files related ****************/ + downloadFile(req, res) { + let file = path.join(process.cwd(), req.query.name); + res.download(file); + } + + uploadFile(req, res) { + + if (req.file) { + console.log(req.file.path); + res.end(req.file.path); + } else { + res.end('upload failed'); + } + } + + uploadFiles(req, res) { + + + if (!req.files || req.files.length === 0) { + res.end('upload failed') + } else { + let files = []; + for (let i = 0; i < req.files.length; ++i) { + files.push(req.files[i].path); + } + + res.end(files.toString()); + } + + } + /**************** END : files related ****************/ + } diff --git a/package.json b/package.json index 22e34c9ee9..a5ce50d3b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmysql", - "version": "0.0.4", + "version": "0.0.5", "description": "One command to generate REST APIs for any MySql database", "main": "index.js", "scripts": {