
Research
NPM targeted by malware campaign mimicking familiar library names
Socket uncovered npm malware campaign mimicking popular Node.js libraries and packages from other ecosystems; packages steal data and execute remote code.
npm install jsoncan
1.1.1
var Jsoncan = require('jsoncan');
// db root, the json files will save here, make sure the path does exist. if not, jsoncan will try to create it.
var PATH = path.join(__dirname, 'data');
// define tables schemas
var tables = {
people: {
id: {
text: 'user id',
type: 'autoIncrement'
},
name: {
text: 'your name',
type: 'string',
max: 30,
min: 2,
required: true
}
}
};
// create a new db, if exists, connect it.
var can = new Jsoncan(PATH, tables);
// create or open a table.
var People = can.open('people'); // can.table('people') do the same thing.
// create table with schemas.
var Doctor = can.open('doctor', schemas);
when a record inserted, a new "_id" value will be assigned to it.
var Tom;
People.insert({name: 'Tom'}, function (e, record) {
Tom = record;
console.log(record); // now, record have a "_id" key
});
// insert multiply records at one time.
People.insertAll([{name: 'David'}, {name: 'Bill'}], function (e, records) {
console.log(records);
});
// find by primary id
People.finder(Tom._id).exec(function (e, record) {...});
// or
People.find(Tom._id).exec(function (e, record) {...});
// sync way
var man = People.find(_id).execSync();
// find by unique id, only used for the uniqued fields.
People.finder('id', Tom.id).exec(function (e, record) {...});
// or
People.findBy('id', Tom.id).exec(function (e, record) {...});
// sync way
var otherMan = People.findBy('name', 'xxx').execSync();
using query() to retrieve multiply records. findAll() is alias.
// query(filters).exec(callback);
Product.query({price: ['>', 100], name: ['like', '%haha%']}).exec(function (e, records) {...} );
// or
Product.findAll(filters).exec(callback);
// using where()
Product.query()
.where('price', '>', 100)
.where('name', 'like', '%haha%')
.exec(callback);
// sync way
var men = People.query({age: ['between', 18, 36]}).execSync();
// chain skip, limit and select
People.query().where(age, ['>=', 18]).order('name').skip(100).limit(10).select('id, name').exec(callback);
// where
// support operators: =, >, <=, <>, !=, in, not in, between, like, pattern.
var query = People.query();
query.where('age', 8).select();
query.where('age', '>', 8).select();
query.where('text', 'like', '%hello%').select();
query.where('name', 'pattern', /^Liu/i).select();
query.where('name', 'in', ['Tom', 'Mike', 'Jobs']).select();
// you can chain them.
query.where('age', '>', 8).where('name', 'Tom').select();
// or use a hash
query.where({age: ['>', 8], name: 'Tom'}).select();
// select ways
query.select() // select all
query.select('id', 'name');
query.select(['id', 'name']);
query.select('id, name');
// order ways
// default is ascend
query.order(age);
// in descend
query.order(age, true);
// skip and limit
query.order('id').skip(3).limit(10);
// exec
query.exec(function (e, records) { ... });
// exec in sync
var records = query.execSync();
// count
query.count(function (e, count) {...});
// count in sync
var count = query.countSync();
// update by primary field
Product.update(product._id, {price: 199.99}, function (e, record) {...});
// update by unique field
User.updateBy('email', user.email, {age: 22}, function (e, record) {...});
// update all
User.updateAll({age: 17}, {class: 'xxx'}, function (e, records) {...});
// sync way
Product.updateSync(product._id, {price: 199.99});
User.updateBySync('email', user.email, {age: 22});
User.updateAllSync({age: 17}, {class: 'xxx'});
// delete one record
User.remove(_id, function (e) {...});
User.removeBy('class', 'xxx', function (e) {...});
// delete mutilple records
User.removeAll({age, 10}, function (e) {...});
// sync way
User.removeSync(_id);
User.removeBySync('class', 'xxx');
User.removeAllSync({age, 10});
There are three ways to create a model object:
var Product = can.open('product');
// create a new one
var productA = Product.create({name: 'xxx'}); // or Product.model({...});
productA.set(price, 2.99);
product.save(function (e, records) {...});
// load exist record from db
// load by primary id
var productB = Product.load('the_primary_id');
// load by unique field
var productC = product.loadBy(an_unique_name, 'xxxx');
// use chain
productA.set(name, 'xxx').save(callback);
// remove
productA.remove(callback);
// sync way
productA.set(price, 2.99).saveSync();
productA.set({name: 'xxx', price: 2.99}).saveSync();
productA.removeSync();
For data safe, jsoncan will always validate the data automatically before save the data into the json file. all the validate rules are defined in field schemas object. the validate part is based on validator.js
so far, you can add these rules.
in insert or update process, if validate failed, it will throw an error.
// suppose name is an unique field in product
var productA = Product.loadBy('name', 'xxx');
productA.set('name', 'a duplicated value').save(function (e, record) {
console.log(e);
// will output
/*
{
[Error: invalid data found, save failed!]
code: 1300,
invalidMessages: { name: 'Duplicated value found, <xxx> already exists'},
invalid: true
}
*/
// so you can use e.invalid to judge whether the error throw by validate.
// and you can get the error messages by e.invalidMessages.
});
you can also validate data in model way
var productA = Product.model({name: 'xxx', price: xxx, label: xxx});
productA.validate(); // return boolean
product.isValid // after validate, isValid will be set true or false
// if failed, messages will be set as a hash object.
validateMessages = productA.messages;
the table schemas defined in a normal hash object. except the above validate rule keys, a schema also support these keys:
field types including:
examples:
var schemas = {
id: {
text: 'user id',
type: 'random',
isUnique: true,
size: 10
},
firstName: {
text: 'first name',
type: 'string',
max: 50,
min: 2,
required: true,
},
lastName: {
type: 'alias',
logic: function (data) {
return [data.firstName, data.lastName].join('.');
}
},
password: {
type: 'password',
size: 30,
required: true
},
passwordConfirm: {
type: 'string',
size: 30,
isFake: true,
validate: function (value, data) {
if (value == undefined || value == '' || value == null) {
return 'please input password confirmation';
} else if (value != data.password) {
return 'twice inputed passwords are not same!';
}
}
},
country: {
text: 'country',
type: 'map',
requred: true,
values: {
'cn': 'China',
'uk': 'England',
'jp': 'Japan',
'us': 'USA'
}
},
age: {
text: 'age',
type: 'int',
default: 10
},
sex: {
text: 'status',
type: 'enum',
values: ['female', 'male']
},
balance: {
text: 'cash balance',
type: 'float',
default: 0.00,
prefix: '$'
},
created: {
type: 'created',
format: function (t) {
var d = new Date(t);
return [d.getFullYear(), d.getMonth() + 1, d.getDate()].join('-') + ' ' + [d.getHours(), d.getMinutes(), d.getSeconds()].join(':');
}
},
modified: {
type: 'modified'
}
};
// then use to create Table.
var People = can.open('people', schemas);
please see the test file.
please see the test file.
// find one with references
Blog.findBy('id', 'id value').ref('categories').hasMany('comments').exec(callback);
// find all with references
Product.query(filters).ref('categories').hasMany('factories').execSync();
Please see the test part.
Please see the performance part.
FAQs
an agile json based database engine
The npm package jsoncan receives a total of 52 weekly downloads. As such, jsoncan popularity was classified as not popular.
We found that jsoncan demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovered npm malware campaign mimicking popular Node.js libraries and packages from other ecosystems; packages steal data and execute remote code.
Research
Socket's research uncovers three dangerous Go modules that contain obfuscated disk-wiping malware, threatening complete data loss.
Research
Socket uncovers malicious packages on PyPI using Gmail's SMTP protocol for command and control (C2) to exfiltrate data and execute commands.