Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase performance #25

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ Returns a table class extended from `Tamotsu.Table`.
|autoIncrement |boolean|If true, id is automatically incremented when its value is blank (Default: true)|
|rowShift |number |Number of rows before the start of the table (Default: 0)|
|columnShift |number |Number of columns before the start of the table (Default: 0)|
|shouldCache |boolean|If true, all data will be cached (Default: false)|

#### Prepared `instanceProperties`
|Key |Type |Description|
Expand Down
2 changes: 1 addition & 1 deletion init.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function initialize(spreadsheet) {
ss_ = spreadsheet || SpreadsheetApp.getActive();
Table = createTable_();
Relation_ = createRelation_();
callbacks_.forEach(function(callback) {
callbacks_.forEach(function (callback) {
callback(spreadsheet);
});
}
Expand Down
182 changes: 100 additions & 82 deletions models/Relation_.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,93 @@
var createRelation_ = function() {
var Relation_ = function(TableClass) {
var createRelation_ = function () {
var Relation_ = function (TableClass) {
this.Table = TableClass;
this.predicates = [];
};

Object.defineProperties(Relation_.prototype, {
where: { value: function(predicate) {
this.predicates.push(predicate);
return this;
}},

all: { value: function() {
var records = [];
var that = this;
this.Table.allValues().forEach(function(values, i) {
var record = new that.Table(that.Table.objectFrom(values), { row_: i + 2 });
var passed = true;
for (var i = 0; i < that.predicates.length; i++) {
passed = passed && evaluate(that.predicates[i], record);
if (!passed) break;
}
if (passed) records.push(record);
});

if (!this.comparator) return records;
return compare(this.comparator, records);
}},

first: { value: function() {
var records = this.all();
return records.length > 0 ? records[0] : null;
}},

last: { value: function() {
var records = this.all();
return records.length > 0 ? records[records.length - 1] : null;
}},

pluck: { value: function(column) {
var result = [];
var that = this;
this.all().forEach(function(record) {
result.push(record[column]);
});
return result;
}},

sum: { value: function(column) {
var total = 0;
var that = this;
this.all().forEach(function(record) {
total += Number(record[column]);
});
return total;
}},

max: { value: function(column) {
return Math.max.apply(null, this.pluck(column));
}},

min: { value: function(column) {
return Math.min.apply(null, this.pluck(column));
}},

order: { value: function(comparator) {
this.comparator = comparator;
return this;
}},
where: {
value: function (predicate) {
this.predicates.push(predicate);
return this;
}
},

all: {
value: function () {
var records = [];
var that = this;
this.Table.allValues().forEach(function (values, i) {
var record = new that.Table(that.Table.objectFrom(values), { row_: i + 2 });
var passed = true;
for (var i = 0; i < that.predicates.length; i++) {
passed = passed && evaluate(that.predicates[i], record);
if (!passed) break;
}
if (passed) records.push(record);
});

if (!this.comparator) return records;
return compare(this.comparator, records);
}
},

first: {
value: function () {
var records = this.all();
return records.length > 0 ? records[0] : null;
}
},

last: {
value: function () {
var records = this.all();
return records.length > 0 ? records[records.length - 1] : null;
}
},

pluck: {
value: function (column) {
var result = [];
var that = this;
this.all().forEach(function (record) {
result.push(record[column]);
});
return result;
}
},

sum: {
value: function (column) {
var total = 0;
var that = this;
this.all().forEach(function (record) {
total += Number(record[column]);
});
return total;
}
},

max: {
value: function (column) {
return Math.max.apply(null, this.pluck(column));
}
},

min: {
value: function (column) {
return Math.min.apply(null, this.pluck(column));
}
},

order: {
value: function (comparator) {
this.comparator = comparator;
return this;
}
},
});
var evaluate = function(predicate, record) {

var evaluate = function (predicate, record) {
var t = typeof predicate;
if (t === 'function') {
return predicate(record);
Expand All @@ -79,51 +97,51 @@ var createRelation_ = function() {
throw 'Invalid where condition [' + predicate + ']';
}
};
var evaludateAsObject = function(object, record) {

var evaludateAsObject = function (object, record) {
var passed = true;
for (var attr in object) {
passed = passed && record[attr] === object[attr];
if (!passed) return false;
}
return true;
};
var compare = function(comparator, records) {

var compare = function (comparator, records) {
var t = typeof comparator;
if (t === 'function') return records.sort(comparator);
if (t === 'string') return records.sort(createComparator(comparator));
throw 'Invalid order comparator [' + comparator + ']';
};
var createComparator = function(strComparator) {

var createComparator = function (strComparator) {
var funcs = [];
strComparator.split(',').forEach(function(part) {
strComparator.split(',').forEach(function (part) {
var attr, order;
[attr, order] = part.trim().split(/\s+(?=(?:asc|desc))/i);
order = (order || 'asc');
if (order.toLocaleLowerCase() === 'asc') {
funcs.push(function(a, b) {
funcs.push(function (a, b) {
if (a[attr] < b[attr]) return -1;
if (a[attr] > b[attr]) return 1;
if (a[attr] > b[attr]) return 1;
return 0;
});
} else if (order.toLocaleLowerCase() === 'desc') {
funcs.push(function(a, b) {
funcs.push(function (a, b) {
if (a[attr] > b[attr]) return -1;
if (a[attr] < b[attr]) return 1;
if (a[attr] < b[attr]) return 1;
return 0;
});
} else {
throw 'Invalid order comparator [' + strComparator + ']';
}
});

return createCombinedComparator(funcs);
};
var createCombinedComparator = function(comparators) {
return function(a, b) {

var createCombinedComparator = function (comparators) {
return function (a, b) {
for (var i = 0; i < comparators.length; i++) {
var r = comparators[i](a, b);
if (r !== 0) return r;
Expand Down
Loading