Giter VIP home page Giter VIP logo

cloudfier's People

Contributors

abstratt avatar renovate-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

cloudfier's Issues

[mean-generator] avoid wrapping promises with additional promises

In the code below, there is no need to wrap the call to Examples.car() in a function:

        return q().all([
            q().then(function() {
                return Examples.car();
            }), ...

Since it returns a promise, we could be passing the result of that expression directly:

        return q().all([
            Examples.car(),
            ...
        ])...

[jee-generator] support for global preconditions

Support for global preconditions.

Example:

    (* Book a taxi that is currently available *)
    operation book(toRent : Taxi)
        (* No taxis available *)
        precondition {
            Taxi extent.exists((t : Taxi) : Boolean { not t.full })
        }
    ...

[mean-generator] pipeline generator is, like, totally broken

The support for asynchronous JS (MEAN) code generation from UML models is not working yet.

Exhibit A: Behavior in the model (a functional test case):

operation rentalHistory();
begin
    var car, customer;
    begin
        car := Examples#newCar();
        customer := Examples#newCustomer();
        customer.rent(car);
        Assert#areEqual(1, customer.rentals.size());
        customer.finishRental();
    end;
    begin
        customer.rent(car);
        Assert#areEqual(2, customer.rentals.size());
    end;
end;

Exhibit B: Approximate desired output (minus known pending support for count):

test('rentalHistory', function(done) {
    var behavior = function() {
        var car;
        var customer;
        return q().all([
            Examples.newCar().then(function(call_newCar) {
                car = call_newCar;
            }), 
            Examples.newCustomer().then(function(call_newCustomer) {
                customer = call_newCustomer;
            })
        ]).then(function() {
            customer.rent(car);
        }).then(function() {
            return Rental.findOne({ _id : customer.rentals }).exec();
        }).then(function(read_rentals) {
            assert.equal(1, /*TBD*/count);
        }).then(function() {
            customer.finishRental();
        }).then(function() {
            customer.rent(car);
        }).then(function() {
            return Rental.findOne({ _id : customer.rentals }).exec();
        }).then(function(read_rentals) {
            assert.equal(2, /*TBD*/count);
        });
    };
    behavior().then(done, done);
});

Exhibit C: Behavior currently generated:

test('rentalHistory', function(done) {
    var behavior = function() {
        var car;
        var customer;
        return q().all([
            q().then(function() {
                return Examples.newCar();
            }), q().then(function() {
                return Examples.newCustomer();
            }).then(function(call_newCustomer) {
                customer = call_newCustomer;
            }), q().then(function() {
                customer.rent(car);
            }), q().then(function() {
                return Rental.findOne({ _id : customer.rentals }).exec();
            }).then(function(read_rentals) {
                assert.equal(1, /*TBD*/count);
            }), q().then(function() {
                customer.finishRental();
            }), q().all([
                q().then(function() {
                    customer.rent(car);
                }), q().then(function() {
                    return Rental.findOne({ _id : customer.rentals }).exec();
                }).then(function(read_rentals) {
                    assert.equal(2, /*TBD*/count);
                })
            ]).spread(function(call_rent, call_areEqual) {
                /*sink*/;
                /*sink*/;
            })
        ]).spread(function(call_newCar, add_customer, call_rent, call_areEqual, call_finishRental, block) {
            car = call_newCar;
            /*sink*/;
            /*sink*/;
            /*sink*/;
            /*sink*/;
            /*sink*/;
        });
    };
    behavior().then(done, done);
});

IOW, still quite a bit of stuff to be worked out...

[jee-generator] failing with NPEs for stale cross-references

Had a model referring to an operation defined elsewhere, and the referred element no longer exists (it was removed but the mmodel not recompiled), so it is an unresolved proxy. Generator fails with NPEs trying to access the parent of the operation.

[mean-generator] need to inline derived boolean properties used in conditions

For instance, in this model:

readonly attribute returned : Date;
derived readonly attribute inProgress : Boolean := {
    self.returned == null
};
static query currentForCustomer(c : Customer) : Rental;
begin
    return Rental extent.\any((l : Rental) : Boolean {
        (l.customer == c) and l.inProgress
    });
end;

inProgress is a derived property, and cannot be used as is in Mongoose queries. We currently generate code for the query method as:

rentalSchema.virtual('inProgress').get(function () {
    return this['returned'] == null;
});

rentalSchema.statics.currentForCustomer = function (c) {
    var me = this;
    return Q().then(function() {
        return Q.npost(me.model('Rental').find().where({
            $and : [ 
                { customer : c },
                { 'inProgress' : true }
            ]
        }).findOne(), 'exec', [  ]);
    });
};

but should be generating something like this:

rentalSchema.statics.currentForCustomer = function (c) {
    var me = this;
    return Q().then(function() {
        return Q.npost(me.model('Rental').find().where({
            $and : [ 
                { customer : c },
                { 'returned' : null }
            ]
        }).findOne(), 'exec', [  ]);
    });
};

[mean-generator] instance query operations not being generated

    derived attribute population  : Integer := { self.computePopulation() };
    query computePopulation() : Integer;
    begin
        return (self.cities.sum((c : City) : Integer { c.population }) as Integer);
    end;

produces this:

/*************************** DERIVED PROPERTIES ****************/

stateSchema.methods.getPopulation = function () {
    var me = this;
    return Q().then(function() {
        return me.computePopulation();
    }).then(function(computePopulationResult) {
        return computePopulationResult;
    });
};

computePopulation is nowhere to be seen though.

Allow singletons

Sometimes classes do not need instantiation, e.g. in case their only purpose is to provide an operation.

Show UML Diagram in Orion enviroment

Validating your designs by having a graphical notation (diagram) is very helpful. Currently the only way to do it is to copy the source code to eclipse and then use the graphviz addin.

[mean-generator] accessing an entity instance may need to re-fetch it first

Consider the case:

    operation availableUponReturn();
    begin
        var car, customer;
        begin
            car := Examples#newCar();
            customer := Examples#newCustomer();
        end;
        begin
            Assert#isTrue(car.available);
            customer.rent(car);
        end;
        begin
            Assert#isTrue(not car.available);
            customer.finishRental();
        end;
        begin
            Assert#isTrue(car.available);
        end;
    end;

Reading the car variable in that last block should trigger a re-fetch - the state we had loaded before is from a different block/transaction/session and no longer current.

[mean-generator] invariants not being enforced

Must generate code enforcing invariants, such as:

    attribute price : Double
        (* Price mustbe $50 at least. *)
        invariant above_minimum { self.price >= 50.0 }
        (* Price cannot be above $500. *)
        invariant below_maximum { self.price <= 500.0 };

and:

    attribute year : Integer
        (* Year must be later than 1990 *)
        invariant above_minimum { (self.year > 1990) }
        (* Year cannot be in the future *)
        invariant below_maximum { self.year <= Date#today().year() };

[jee-generator] support projecting attributes/values in JPA queries

Examples:

    static query expenseDetails() : { reporter : Employee, category: String, expenseAmount : Double }[*];
    begin
        return Expense extent.collect((e : Expense) : { reporter : Employee, category : String, expenseAmount : Double } {
            {
                reporter := e.employee,
                category := e.category.name,
                expenseAmount := e.amount
            }
        });
    end;

[jee-generator] generation of "group by" queries

Implement generation of "group by" queries. Also, need to implement at least sum/one so the "cities" example works. Example of an aggregation query using the count aggregation function:

    static query openExpenseCountPerCategory() : { category : Category, count : Integer }[*];
    begin
        return Expense extent.select((e : Expense) : Boolean {
            e.status == Status#Submitted
        }).groupBy(
            (e : Expense) : Category { e.category }
        ).groupCollect((group : Expense[*]) : { category : Category, count : Integer } {
            {
                category := group.one().category,
                count := group.size()
            }
        });
    end;

And the code to be generated:

    public Collection<Tuple> openExpenseCountPerCategory() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Tuple> cq = cb.createTupleQuery();
        Root<Expense> expense_ = cq.from(Expense.class);
        TypedQuery<Tuple> query = entityManager.createQuery(
            cq.multiselect(
                expense_.get("category").get("id").alias("category"), 
                cb.count(expense_).alias("count")
            )
            .where(cb.equal(expense_.get("status"), Expense.Status.Submitted))
            .groupBy(expense_.get("category").get("id"))
        );
        return query.getResultList();
    }

[mean-generator] must save objects created during an action

The Rental object created in the rent action below is not being saved.

customerSchema.methods.rent = function (car) {
    var rental;
    var me = this;
    return Q().then(function() {
        return Q().then(function() {
            console.log("rental = new Rental();\n");
            rental = new Rental();
        });
    }).then(function() {
        return Q().then(function() {
            console.log("rental.customer = me._id;\nme.rentals.push(rental._id);\n");
            rental.customer = me._id;
            me.rentals.push(rental._id);
        });
    }).then(function() {
        return Q().then(function() {
            console.log("rental.car = car._id;\ncar.rentals.push(rental._id);\n");
            rental.car = car._id;
            car.rentals.push(rental._id);
        });
    }).then(function() {
        return Q().then(function() {
            console.log("car.carRented();\n");
            car.carRented();
        });
    }).then(function() {
        return Q.npost(me, 'save', [  ]).then(function(saveResult) {
            return saveResult[0];
        });
    });
};

[runtime] error running tests in cities app: Error finding converter for cities::State to convert

Error running tests in the cities application. There is an assumption in RuntimeObject that will treat a related object as a simple object if there is no association, which is the case if a DataType has a slot that is a Class (entity).

 cloudfier run-tests .
✘ cities_tests.Tests.populousStates
    Cause: java.lang.RuntimeException: Error finding converter for cities::State to convert cities::State#38 = {values: {name=California, acronym=CA} - children: {} - related: {}}
✔ cities_tests.Tests.statePopulation

[jee-generator] support for helper query methods

One may want to reuse some query logic in a model by defining a helper operation that takes a collection as a parameter and then applies a filter based on other parameters (so it can filter the input collection - which may come from any source - according to different criteria). The JEE generator is not dealing well with this, so we changed the models so that was no longer done (by inlining the helper operations).

See:

[mean-generator] derived conditions not working

Derived conditions are not working. This model:

Assert#isTrue(not car.available);

is currently resulting in this:

assert.strictEqual(car['available'], true);

but 'available' is a derived property:

derived attribute available : Boolean := {
    self.status == Status#Available
};

which maps to this:

carSchema.virtual('available').get(function () {
return this['status'] == "Available";
});

but somehow that is not currently working, why is yet TBD.

building is failing

For two weeks now, due to a partial commit...

ERROR] 
ERROR:  SubQueryActionGenerator.xtend - 
41: The method generateTraverseRelationshipAction(InputPin, Property) of type SubQueryActionGenerator must override a superclass method.

[runtime] renaming tuple slot names leads to missing data

Anonymous tuples with omitted/mismatched names pass type verification but data that changed name is not available downstream.

For instance, this query:

        return City extent.groupBy((c : City) : State {
            c.cityState
        }).groupCollect((cities : City[*]) : { : String,  : Integer} {
            {
                cityState := cities.one().cityState.abbreviation, 
                statePopulation := cities.sum((c : City) : Integer {
                    c.population
                })
            }
        }).select((aggregated : { cityState : String, statePopulation : Integer}) : Boolean {
            aggregated.statePopulation > threshold
        }).collect((aggregated : { acronym : String, statePopulation : Integer}) : String {
            aggregated.acronym
        });

would result in a collection with a an empty string (probabaly a sanitized null). For it to work, I had to change the final collect to:

        }).collect((aggregated : { cityState : String, statePopulation : Integer}) : String {
            aggregated.cityState
        });

because cityState is how the slot was named when the tuple data was projected (in groupCollect). We must either forbid those renames when consuming tuples (type clash), or we restructure the internal data so we can use the new names.

[jee-generator] query generation does not deal well with inheritance

For instance, in carserv:

    public Collection<Customer>  findByName(String firstName, String lastName) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
        Root<Customer> customer_ = cq.from(Customer.class);
        return entityManager.createQuery(
            cq.select(customer_).distinct(true).where(
                cb.or(
                    cb.equal(
                        cb.parameter(String.class, "lastName"),
                        person_.get("lastName")
                    ),
                    cb.equal(
                        cb.parameter(String.class, "firstName"),
                        person_.get("firstName")
                    )
                )
            )
        ).setParameter("firstName", firstName).setParameter("lastName", lastName).getResultList();
    }

The person_ alias is bogus, and results from the attributes being inherited from a Person class.

[jee-generator] generation of filtering for grouped results (having)

Related to issue #30. Example:

model crm;
class Customer
    attribute name : String;
    attribute title : String;              
    query countByTitle() : {title : String, customerCount : Integer} [*];
    begin
        return Customer extent.groupBy((c : Customer) : String {
            c.title
        }).groupCollect((group : Customer[*]) : {title:String, customerCount : Integer} {
            { 
                title := group.one().title,
                customerCount := group.size()
            }   
        }).select((counted : {title:String, customerCount : Integer}) : Boolean {
            counted.customerCount > 100
        });
    end;
end;
end.

produces (core only):

cq
    .groupBy(customer_.get("title"))
    .multiselect(customer_.get("title"), cb.count(customer_))
    .having(cb.greaterThan(cb.count(customer_), cb.literal(100)))

Presets in dropdowns

An existing many to one relationship does not show the actual setting once you call the edit screen. So for example, if I have a crude oil from a specified region (e.g. terra nova from europe) it doesn't necessarly show europe in the edit screen (e.g. asia pacific instead of europe in the dropdown). Instead it takes "the first one" for whatever reason.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.