Skip to content

Instantly share code, notes, and snippets.

@afiore
Created June 7, 2010 12:14
Show Gist options
  • Save afiore/428600 to your computer and use it in GitHub Desktop.
Save afiore/428600 to your computer and use it in GitHub Desktop.
Parses a Javascript data structure (e.g the content of a mongodb collection) and infers a schema definition
/**
* Map_schema.js
*
* Parses a Javascript data structure (e.g the content of a mongodb collection)
* and populates a schema definition with its attribute names and types.
*
*/
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (value instanceof Array) {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
var db=[
{'a': 33, 'b': {
'bb' : 44,
'bc' : {
'bcc': null
},
'bd' : null,
'be' : true,
'bf' : false
},
'c': null
},
{'x':{'bf':false,'xx':22}},
{'y':[2,3,4,5]},
{'z': {'za':[1,3,4,{'zaa':22}]}}
]
schema={};
var parse_struct=function(obj,parents){
var parents=(parents) ? parents : [];
print('-----------------------------');
print('receiving:'+parents.join('.'));
var child_attr_count=0;
var attr_count = 0;
for (attr in obj) attr_count++;
var i=attr_count;
for (attr in obj) {
print('i='+i);
var child_attr_count=0;
//count attributes in child attribute
for(child_attr in obj[attr]) child_attr_count++;
var separator=(parents.length > 0) ? '.' : '';
var path=parents.join('.')+separator+attr;
if (!schema[path] && isNaN(parseInt(attr))) {
print(attr+'=>'+child_attr_count);
schema[path] = typeOf(obj[attr]);
}
// add to parents if child attribute exists and
// it is not a numeric key
if (child_attr_count > 0 && isNaN(parseInt(attr))) {
parents.push(attr);
}
//remove parent when no sibling elements exist (i.e. i==1)
if (parents.length > 0 && i == 1 && child_attr_count == 0) {
var p= parents.pop()
print('popping '+p);
}
i--;
print('sending:'+parents.join(''))
parse_struct(obj[attr],parents);
}
}
print(db.toSource());
parse_struct(db,[]);
print(schema.toSource());
//output
//{'a:"number", b:"object", 'b.bb':"number", 'b.bc':"object", 'b.bc.bcc':"null", 'b.bd':"null", 'b.be':"boolean", 'b.bf':"boolean", c:"null", x:"object", 'x.bf':"boolean", 'x.xx':"number", y:"array", z:"object", 'z.za':"array", 'z.za.zaa':"number"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment