Skip to content

Commit

Permalink
Merge branch 'master' into pressure-wash
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarcaso committed Jan 23, 2019
2 parents ed63a8a + e960229 commit db8c565
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 91 deletions.
32 changes: 15 additions & 17 deletions src/com/google/foam/demos/sevenguis/FlightBooker.js
Expand Up @@ -25,27 +25,28 @@ foam.CLASS({
'foam.u2.tag.Select'
],

imports: [ 'window' ],
exports: [ 'as data' ],

css: `
^ { padding: 10px; }
^ .error { border: 2px solid red; }
^title { font-size: 18px; }
^title, ^ button, ^ input, ^ select {
width: 160px; height: 24px; margin: 5px;
width: 160px; height: 24px; margin: 8px 0; display: block;
}
`,

properties: [
{
class: 'Boolean',
name: 'oneWay',
name: 'isReturn',
value: true,
view: {
class: 'foam.u2.view.ChoiceView',
choices: [
[ true, 'one-way flight' ],
[ false, 'return flight' ]
[ false, 'one-way flight' ],
[ true, 'return flight' ]
]
}
},
Expand All @@ -63,13 +64,9 @@ foam.CLASS({
class: 'Date',
name: 'returnDate',
factory: function() { return new Date(Date.now()+2*3600000*24); },
validateObj: function(oneWay, returnDate, departDate) {
if ( ! oneWay && foam.Date.compare(returnDate, departDate) < 0 ) return 'Must not be before depart date.';
validateObj: function(isReturn, returnDate, departDate) {
if ( isReturn && foam.Date.compare(returnDate, departDate) < 0 ) return 'Must not be before depart date.';
}
},
{
name: 'returnDateMode',
expression: function(oneWay) { return oneWay ? 'disabled' : 'rw'; }
}
],

Expand All @@ -78,10 +75,11 @@ foam.CLASS({
this.SUPER();
this.nodeName = 'div';
this.
start('div').addClass('^title').add('Book Flight').end().
add(this.ONE_WAY).tag('br').
add(this.DEPART_DATE).tag('br').
start(this.RETURN_DATE).attrs({mode: this.returnDateMode$}).end().tag('br').
addClass(this.myClass()).
start('div').addClass(this.myClass('title')).add('Book Flight').end().
add(this.IS_RETURN).
add(this.DEPART_DATE).
start(this.RETURN_DATE).show(this.isReturn$).end().
add(this.BOOK);
}
],
Expand All @@ -93,9 +91,9 @@ foam.CLASS({
code: function() {
var depart = this.departDate.toLocaleDateString();

window.alert('You have booked a ' + (this.oneWay ?
'one-way flight on ' + depart :
'flight departing on ' + depart + ' and returning ' + this.returnDate.toLocaleDateString() ) + '.');
this.window.alert('You have booked a ' + (this.isReturn ?
'flight departing on ' + depart + ' and returning ' + this.returnDate.toLocaleDateString():
'one-way flight on ' + depart) + '.');
}
}
]
Expand Down
7 changes: 7 additions & 0 deletions src/foam/comics/BrowserView.js
Expand Up @@ -90,6 +90,11 @@ foam.CLASS({
name: 'exportEnabled',
documentation: 'True to enable the export button.'
},
{
class: 'Boolean',
name: 'exportCSVEnabled',
documentation: 'True to enabled the export as CSV button'
},
{
class: 'Boolean',
name: 'toggleEnabled',
Expand All @@ -109,6 +114,7 @@ foam.CLASS({
selectEnabled,
addEnabled,
exportEnabled,
exportCSVEnabled,
toggleEnabled,
detailView
) {
Expand All @@ -123,6 +129,7 @@ foam.CLASS({
config.detailView = detailView;
config.editEnabled = editEnabled;
config.exportEnabled = exportEnabled;
config.exportCSVEnabled = exportCSVEnabled;
config.selectEnabled = selectEnabled;
config.toggleEnabled = toggleEnabled;

Expand Down
39 changes: 38 additions & 1 deletion src/foam/comics/DAOController.js
Expand Up @@ -23,6 +23,7 @@ foam.CLASS({
requires: [
'foam.comics.SearchMode',
'foam.u2.borders.NullBorder',
'foam.nanos.export.CSVDriver'
],

topics: [
Expand All @@ -37,6 +38,12 @@ foam.CLASS({
{
name: 'predicate'
},
{
name: 'csvDriver',
factory: function() {
return this.CSVDriver.create();
}
},
{
name: 'filteredDAO',
view: { class: 'foam.u2.view.ScrollTableView' },
Expand Down Expand Up @@ -81,6 +88,12 @@ foam.CLASS({
documentation: 'True to enable the export button.',
value: true
},
{
class: 'Boolean',
name: 'exportCSVEnabled',
documentation: 'True to enable export csv button',
value: false
},
{
class: 'Boolean',
name: 'toggleEnabled',
Expand Down Expand Up @@ -217,8 +230,32 @@ foam.CLASS({
name: 'export',
isAvailable: function(exportEnabled) { return exportEnabled; },
code: function() {
this.pub('export', this.filteredDAO)
this.pub('export', this.filteredDAO);
}
},
{
name: 'exportCSV',
label: 'Export as CSV',
icon: 'images/export-icon-resting.svg',
isAvailable: function(exportCSVEnabled) { return exportCSVEnabled; },
code: function() {
this.downloadCSV(this.filteredDAO);
}
}
],

listeners: [
function downloadCSV(data) {
this.csvDriver.exportDAO(this.__context__, data)
.then(function(result) {
result = 'data:text/csv;charset=utf-8,' + result;
var encodedUri = encodeURI(result);
var link = document.createElement('a');
link.setAttribute('href', encodedUri);
link.setAttribute('download', 'data.csv');
document.body.appendChild(link);
link.click();
});
}
]
});
45 changes: 28 additions & 17 deletions src/foam/dao/EnabledAwareDAOTest.js
Expand Up @@ -9,6 +9,13 @@ foam.CLASS({
name: 'EnabledAwareDAOTest',
extends: 'foam.nanos.test.Test',

javaImports: [
'foam.core.FObject',
'foam.core.X',
'foam.nanos.auth.EnabledAwareDummy',
'java.util.List',
],

methods: [
{
name: 'runTest',
Expand All @@ -25,37 +32,41 @@ foam.CLASS({
{ type: 'Context', name: 'x' }
],
javaCode: `
foam.dao.DAO delegate = new foam.dao.MDAO(foam.nanos.auth.User.getOwnClassInfo());
dao_ = (foam.dao.DAO) new EnabledAwareDAO.Builder(x)
.setDelegate(delegate).build();
DAO delegate = new foam.dao.MDAO(EnabledAwareDummy.getOwnClassInfo());
dao_ = (DAO) new EnabledAwareDAO.Builder(x)
.setDelegate(delegate)
.build();
enabled_ = new foam.nanos.auth.User.Builder(x)
.setId(1).setEnabled(true).build();
enabled_ = new EnabledAwareDummy.Builder(x)
.setId(1)
.setEnabled(true)
.build();
enabled_ = dao_.put(enabled_);
disabled_ = new foam.nanos.auth.User.Builder(x)
.setId(2).setEnabled(false).build();
disabled_ = new EnabledAwareDummy.Builder(x)
.setId(2)
.setEnabled(false)
.build();
disabled_ = dao_.put(disabled_);
`
},
{
name: 'EnabledAwareDAOTest_find_disabled_returns_null',
javaCode: `
foam.core.FObject found = dao_.find(enabled_.getProperty("id"));
foam.core.FObject notFound = dao_.find(disabled_.getProperty("id"));
FObject found = dao_.find(enabled_.getProperty("id"));
FObject notFound = dao_.find(disabled_.getProperty("id"));
test(found != null && notFound == null, "Find disabled entity returns null");
`
},
{
name: 'EnabledAwareDAOTest_select_do_not_include_disabled',
javaCode: `
foam.dao.ArraySink sink = (foam.dao.ArraySink) dao_.select(new foam.dao.ArraySink());
java.util.List array = sink.getArray();
foam.core.FObject found = (foam.core.FObject) array.get(0);
ArraySink sink = (ArraySink) dao_.select(new ArraySink());
List array = sink.getArray();
test(
array.size() == 1 && foam.util.SafetyUtil.equals(found, enabled_)
array.contains(enabled_) && ! array.contains(disabled_)
, "Select does not include disabled entity"
);
`
Expand All @@ -67,10 +78,10 @@ foam.CLASS({
name: 'javaExtras',
buildJavaClass: function(cls) {
cls.extras.push(`
private foam.core.X x_;
private foam.dao.DAO dao_;
private foam.core.FObject enabled_;
private foam.core.FObject disabled_;
private X x_;
private DAO dao_;
private FObject enabled_;
private FObject disabled_;
`);
}
}
Expand Down
56 changes: 27 additions & 29 deletions src/foam/dao/MDAO.java
Expand Up @@ -13,8 +13,6 @@
import foam.mlang.sink.GroupBy;
import foam.nanos.logger.Logger;
import java.util.ArrayList;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.List;

/**
Expand Down Expand Up @@ -43,13 +41,12 @@ The base AltIndex has two complete subindexes (each holds the entire DAO).
public class MDAO
extends AbstractDAO
{
protected AltIndex index_;
protected Object state_;
protected ReadWriteLock lock_ = new ReentrantReadWriteLock();
protected AltIndex index_;
protected Object state_ = null;
protected Object writeLock_ = new Object();

public MDAO(ClassInfo of) {
setOf(of);
state_ = null;
index_ = new AltIndex(new TreeIndex((PropertyInfo) this.of_.getAxiomByName("id")));
}

Expand All @@ -65,19 +62,28 @@ public void addIndex(PropertyInfo... props) {
for ( PropertyInfo prop : props ) addUniqueIndex(prop);
}

synchronized Object getState() {
return state_;
}

synchronized void setState(Object state) {
state_ = state;
}

public FObject put_(X x, FObject obj) {
// Clone and freeze outside of lock to minimize time spent under lock
obj = obj.fclone();
obj.freeze();

synchronized ( lock_.writeLock() ) {
synchronized ( this.writeLock_ ) {
FObject oldValue = find(obj);
Object state = getState();

if ( oldValue != null ) {
state_ = index_.remove(state_, oldValue);
state = index_.remove(state, oldValue);
}

state_ = index_.put(state_, obj);
setState(index_.put(state, obj));
}

onPut(obj);
Expand All @@ -88,11 +94,11 @@ public FObject remove_(X x, FObject obj) {
if ( obj == null ) return null;

FObject found;
synchronized ( lock_.writeLock() ) {
synchronized ( this.writeLock_ ) {
found = find(obj);

if ( found != null ) {
state_ = index_.remove(state_, found);
setState(index_.remove(getState(), found));
}
}

Expand All @@ -106,16 +112,14 @@ public FObject remove_(X x, FObject obj) {
public FObject find_(X x, Object o) {
Object state;

synchronized ( lock_.readLock() ) {
state = state_;
}
state = getState();

if ( o == null ) return null;

return AbstractFObject.maybeClone(
getOf().isInstance(o)
? (FObject) index_.planFind(state, getPrimaryKey().get(o)).find(state, getPrimaryKey().get(o))
: (FObject) index_.planFind(state, o).find(state,o)
? (FObject) index_.planFind(state, getPrimaryKey().get(o)).find(state, getPrimaryKey().get(o))
: (FObject) index_.planFind(state, o).find(state,o)
);
}

Expand All @@ -126,11 +130,7 @@ public Sink select_(X x, Sink sink, long skip, long limit, Comparator order, Pre
// use partialEval to wipe out such useless predicate such as: And(EQ()) ==> EQ(), And(And(EQ()),GT()) ==> And(EQ(),GT())
if ( predicate != null ) simplePredicate = predicate.partialEval();

Object state;

synchronized ( lock_.readLock() ) {
state = state_;
}
Object state = getState();

// We handle OR logic by seperate request from MDAO. We return different plan for each parameter of OR logic.
if ( simplePredicate instanceof Or ) {
Expand All @@ -149,7 +149,7 @@ public Sink select_(X x, Sink sink, long skip, long limit, Comparator order, Pre
}

// TODO: if plan cost is >= size, log a warning
if ( state != null && predicate != null && plan.cost() > 1000 && plan.cost() >= index_.size(state_) ) {
if ( state != null && predicate != null && plan.cost() > 1000 && plan.cost() >= index_.size(state) ) {
Logger logger = (Logger) x.get("logger");
logger.error(predicate.createStatement(), " Unindexed search on MDAO");
}
Expand All @@ -160,14 +160,12 @@ public Sink select_(X x, Sink sink, long skip, long limit, Comparator order, Pre
}

public void removeAll_(X x, long skip, long limit, Comparator order, Predicate predicate) {
synchronized ( lock_.writeLock() ) {

if ( predicate == null ) {
state_ = null;
} else {
super.removeAll_(x, skip, limit, order, predicate);
if ( predicate == null ) {
synchronized ( this.writeLock_ ) {
setState(null);
}

} else {
super.removeAll_(x, skip, limit, order, predicate);
}
}
}
2 changes: 1 addition & 1 deletion src/foam/nanos/auth/DeletedAware.js
Expand Up @@ -45,4 +45,4 @@ foam.CLASS({
name: 'deleted'
}
]
})
});

0 comments on commit db8c565

Please sign in to comment.