I want to store files in an existing postgreSQL database by uploading them by means of an express server.
The file comes into the POST end point like this:
{ name: 'New Data.xlsx',
data: <Buffer 50 4c 03 04 14 01 06 00 08 00 00 24 21 00 1f 0a 93 21 cf 02 00 00 4f 1f 00 00 13 00 08 02 5b 43 6f 6e 74 65 6e 74 ... >,
size: 6880975,
encoding: '7bit',
tempFilePath: '',
truncated: false,
mimetype: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
md5: '535c8576e1c94d169ea5a637487ee3b4',
mv: [Function: mv] }
This is a fairly large excel document. Word Docs, pdfs, simple CSVs, etc also need to be possible for upload.
I've tried both node-postgres and sequelize libraries in a similar way:
app.post('/upload', async(req, res) => {
var {upload} = req.files
var data = upload.data
console.log(data);
const x = await pool.query(`insert into attachment (data, file_name, category) values (${data}, '${upload.name}', 'test')`)
// Deconstruct x to get response values
res.send("OK")
});
Some files like txt, plain csv files work and do upload however I receive errors such as
error: invalid message format
for excel or word files.
I've done something like this before with MongoDB but I can't switch databases. Another idea I had was to simply store the files on the production server in an 'uploads' files but I'm not sure that's good practice.
Any advice?
Solved using query parameters.
app.post('/upload', async(req, res) => {
var {upload} = req.files
var data = upload.data
const x = await pool.query(`insert into attachment (data, file_name, category) values ($1, '${upload.name}', 'test')`, [data])
res.send("OK")
});
const cp = require("child_process");
ls = cp.spawn("node", ["./scripts/test.js"]);
ls.stdout.on("data", (data) => {
console.log(`stdout": ${data}`);
const result = data.toString();
});
In ls.stdout.on i am getting data as buffer and if i do it to data.toString()
it gives me result like "{evenNumberSum :8, oddNumberSum:6}" but i want result as a JSON object i am not even able to parse this type of result can anyone give me a better way to get result from buffer
CurrentOutput:
<Buffer 7b 3a 6e 61 6d 65 3d 3e 22 4a 6f 68 6e 22 2c 20 3a 61 67 65 3d 3e 33 30 2c 20 3a 63 69 74 79 3d 3e 22 4e 65 77 20 59 6f 72 6b 22 7d 0a>
Required Output:
{evenNumberSum :8, oddNumberSum:6}
test.js
let result = {};
function add(val1, val2) {
return val1 + val2;
}
result.evenNumbersSum = add(2, 4);
result.oddNumbersSum = add(1, 3);
result.mixNumbersSum = add(1, 2);
console.log(result);
I am not sure what test.js looks like, but I was not able to reproduce this issue.
I am using the following code..
--EDIT/DISCLAIMER-- People are most likely downvoting this because the solution I provided uses eval. To summarize:
YOU SHOULD USE eval AS LITTLE AS POSSIBLE (in a perfect world, eval would never be used)
ONLY USE IT ON *TRUSTED* strings (aka DO NOT USE eval ON USER SUPPLIED DATA!!! EVER.)
Considering the disclaimer above, the only way I could get this to work was:
main.js:
const cp = require('child_process');
ls = cp.spawn('node', ['./test.js']);
ls.stdout.on('data', (data) => {
const dataString = data.toString();
const dataJson = eval(`(${dataString})`);
console.log('Data as JSON =', dataJson);
console.log('evenNumberSum =', dataJson.evenNumberSum);
console.log('oddNumberSum =', dataJson.oddNumberSum);
});
test.js:
console.log({ evenNumberSum: 8, oddNumberSum: 6 });
Which produces the following output:
Data as JSON = { evenNumberSum: 8, oddNumberSum: 6 }
evenNumberSum = 8
oddNumberSum = 6
I'm trying to load data from memcached (EDIT: using the nodejs memcached package) but I keep getting back something like :
{ available_ads: <Buffer 5b 7b 22 69 64 22 3a 37 31 34 31 35 2c 22 74 69 74 6c
65 22 3a 22 44 6f 6c 6c 61 72 53 68 61 76 65 43 6c 75 62 2e 63 6f 6d 22 2c 22 73
75 62 74 69 74 6c ...>, cas: '2' }
I don't know much about memcached so maybe it's because of an invalid character. Here's the output from telnet:
[{"id":71415,"title":"DollarShaveClub.com","subtitle":"","body":"Our Blades Are F***ing Great","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=71415&src=json","image_url":"http:\/\/img.youtube.com\/vi\/ZUG9qYTJMsI\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":null,"min_age":null,"is_vc_ok":true,"width":500,"height":311,"length":94,"is_autoplay":false,"is_responsive":true,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":70799,"title":"Watch Settlers Online video!","subtitle":"","body":"Watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=70799&src=json","image_url":"http:\/\/img.youtube.com\/vi\/1sZKP0QnIIY\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":29,"min_age":21,"is_vc_ok":true,"width":520,"height":325,"length":50,"is_autoplay":false,"is_responsive":true,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":70797,"title":"Watch this Samsung Memory - Meet Loading Ball Larry video!","subtitle":"","body":"Please watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=70797&src=json","image_url":"http:\/\/s3.amazonaws.com\/V11\/images\/982727944edee812a1a8c874a9abf65a.png","cpa":"1","engagement_type":1,"image_width":125,"image_height":79,"currency":"","gender":null,"max_age":34,"min_age":18,"is_vc_ok":true,"width":500,"height":310,"length":103,"is_autoplay":false,"is_responsive":true,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":72006,"title":"Nike: No Cup is Safe","subtitle":"","body":"Please watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=72006&src=json","image_url":"http:\/\/img.youtube.com\/vi\/1jRoHGq9EoY\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":null,"min_age":null,"is_vc_ok":true,"width":300,"height":250,"length":63,"is_autoplay":false,"is_responsive":false,"platforms":["web"],"supported_events":["play","complete"]},{"id":72049,"title":"Behind the Cameras - by Rolex","subtitle":"","body":"Please watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=72049&src=json","image_url":"http:\/\/img.youtube.com\/vi\/k9o1lAq4zTw\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":null,"min_age":null,"is_vc_ok":true,"width":520,"height":325,"length":39,"is_autoplay":false,"is_responsive":false,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":72055,"title":"Huggies - Meet the Squirmers!","subtitle":"","body":"Please watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=72055&src=json","image_url":"http:\/\/img.youtube.com\/vi\/tZnzHq3_xaQ\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":null,"min_age":null,"is_vc_ok":true,"width":300,"height":250,"length":33,"is_autoplay":false,"is_responsive":false,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":70794,"title":"Open Days 2012","subtitle":"","body":"Please watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=70794&src=json","image_url":"http:\/\/img.youtube.com\/vi\/t4TnaVXQCa4\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":"f","max_age":null,"min_age":null,"is_vc_ok":true,"width":520,"height":325,"length":58,"is_autoplay":false,"is_responsive":true,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":70795,"title":"Samsung Memory - Loading Ball Larry","subtitle":"","body":"Please watch the entire video.","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=70795&src=json","image_url":"http:\/\/img.youtube.com\/vi\/a5S668LyM5c\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":100,"min_age":30,"is_vc_ok":true,"width":520,"height":325,"length":103,"is_autoplay":false,"is_responsive":true,"platforms":["web","mobile"],"supported_events":["play","complete"]},{"id":71522,"title":"Huggies Snug & Dry","subtitle":"","body":"Watch the dads test out Huggies at the mall","click_url":"http:\/\/b.v11media.com\/click?k=eeacbb44ecf52873acd8cfbe63ffdbea&uid=111&ip_list=%5B%2298.143.242.51%22%2C%2210.122.186.15%22%5D&o=71522&src=json","image_url":"http:\/\/img.youtube.com\/vi\/Kthn6DkQVL4\/0.jpg","cpa":"1","engagement_type":1,"image_width":480,"image_height":360,"currency":"","gender":null,"max_age":null,"min_age":18,"is_vc_ok":true,"width":520,"height":325,"length":33,"is_autoplay":false,"is_responsive":true,"platforms":["web","mobile"],"supported_events":["play","complete"]}]
Can anyone tell me why the nodejs library would output a buffer tag?
EDIT: here's my code
var Memcached = require('memcached');
var memcached = new Memcached('localhost:11211');
memcached.gets('available_ads', function(err, data){
if(err){ console.log(err); }
console.log(data);
res.json({'click_url' : data});
});
try using:
data.toString();
and then you'll probably need to use JSON.parse:
JSON.parse(data.toString());
It is when you store/set you'll need to store as String.
Example:
mc.set('keyName', JSON.stringify(thisObj), {expires:0}, function(err, val){
if (err) {
callback(err);
} else {
callback(null, thisObj);
}
});
Then when you read it back, just read it as normal json.
Example:
mc.get('keyName', async function(err, data){
callback(null, JSON.parse(data));
}
I'm using gulp to build a stream of glob-matched files and move them all, in their nested structure, to a new location. To do this, I first wanted to build a simple 'through' stream to see what I get passed if I pipe to it from gulp.src().
Here is my test gulpfile.js:
var through = require("through");
var fs = require("fs");
function write(file) {
console.log(file);
console.log(file.toString());
}
gulp.task("move", function () {
return gulp.src("./**")
.pipe(through(write));
});
If I run the gulp 'move' task on the command line, I get output like the following:
<File "some/path">
[object Object]
<File "some/path/file.js" <Buffer 2f 2a 0a 0a 4f 72 67 69 6e 61 6c 20 53 74 79 6c 65 20 66 72 6f 6d 20 65 74 68 61 6e 73 63 68 6f 6f 6e 6f 76 65 72 2e 63 6f 6d 2f 73 6f 6c 61 72 69 7a 65 ...>>
[object Object]
What are those objects? How can I interact with them?
Those are vinyl objects. They are the core data type passed through gulp streams. The contain information about the file (such as path info and contents as a buffer or stream). You can see the data better using gulp-debug.
If you want to move a bunch of files, while preserving their relative path, you can do one of the following, no need to dig into the code yourself:
gulp.src('/a/single/src/path/**/*.foo').pipe(gulp.dest('/a/single/dest/path'));
Or, if you have a bunch of different globs:
gulp.src(['/a/src/path/foo/**/*.foo', '/a/src/path/bar/**/*.bar'], {base: '/a/src/path/'})
.pipe(gulp.dest('/a/dest/path/'));
Mostly you'll be using gulp plugins to manipulate the files, then passing the result to gulp.dest(), rather than manipulating them yourself.
If you need to manipulate the files, there's a few plugins that can help:
gulp-tap allows you to peak into the stream, and optionally modify the file or buffer.
vinyl-map lets you easily modify the contents of files
gulp-filter can help you filter the stream if globbing doesn't work.
You can view the file properties using this js:
var propValue;
for(var propName in file) {
propValue = file[propName];
console.log('name:' + propName, ', value:<<<',propValue,'>>>');
}
Sample Output
name:history , value:"C:\Temp\test.txt"
name:cwd , value:"C:\Temp"
name:base , value:"C:\Temp"
name:_contents , value: full file contents
name:isBuffer , value:"function () {
name:isStream , value:"function () {
name:isNull , value:"function () {
name:isDirectory , value:"function () {
name:clone , value:"function (opt) {
name:pipe , value:"function (stream, opt) {
name:inspect , value:"function () {
name:stat , value:<<< { dev: 0,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
ino: 0,
size: 874,
atime: Sat Sep 19 2015 14:34:51 GMT+1000 (AUS Eastern Standard Time),
mtime: Sat Sep 19 2015 14:34:51 GMT+1000 (AUS Eastern Standard Time),
ctime: Sat Sep 12 2015 14:59:40 GMT+1000 (AUS Eastern Standard Time) } >>>
Usage:
console.log('file name:', file.relative);
console.log('file current working directory:', file.cwd);
console.log('file isDirectory:', file.isDirectory());
For those who also stumbled upon this and don't want to use gulp, here is how I did it:
Assuming files is an array of vinyl objects -
const outputPath = ... // some directory path
files.forEach(file => {
const filePath = path.join(outputPath, file.relative);
// if its a directory then create the directory if not already present
if (file.isDirectory()) {
if (!fs.existsSync(filePath)) {
fs.mkdirSync(filePath, { recursive: true });
}
} else {
// if its a file then save the contents of the file
fs.writeFileSync(filePath, file.contents);
}
});