[eobjects] #858: UpdateableRow for crud operations

1 view
Skip to first unread message

eobjects

unread,
May 23, 2012, 6:16:42 PM5/23/12
to dataclean...@googlegroups.com
#858: UpdateableRow for crud operations
-------------------------+---------------------------
Reporter: w.cazander | Owner:
Type: enhancement | Status: new
Priority: medium | Milestone: MetaModel 3.0
Component: MetaModel | Keywords:
-------------------------+---------------------------
Influenced classes:
org.eobjects.metamodel.data.Row

-------------------------+---------------------------
Have refactored my q&d MM crud code to support generic MetaModel crud
operations.

This implementation wraps on top of normal UpdateableDataContext for
direct usage and it makes sure all primary keys columns are always read
only and can't work on tables without primary keys.

Got stuck in table.getPrimaryKeys() which returned always no columns, so
there is some hardcoded id column search so it could be tested see
UpdateableRowDataContextImpl.getPrimaryKeysForTable

Sample code:
{{{
// Get DataContext
dataContext = dataContextProvider.getDataContext();
if ((dataContext instanceof UpdateableDataContext)==false) {
// throw or handle
}

// Wrap to UpdateableRowDataContext and get table to test with.
dataContextCrud = new
UpdateableRowDataContextImpl((UpdateableDataContext)dataContext);
Table table =
dataContextCrud.getDefaultSchema().getTableByName("table_name");

// Lets add an record.
UpdateableRow newRow = dataContextCrud.createRow(table);
newRow.setValue("name", "test 456");
newRow.setValue(table.getColumnByName("active"), true);
dataContextCrud.persist(newRow);

// Fetch and update and delete data.
DataSet ds =
dataContextCrud.query().from(table).select(table.getColumns()).execute();
int delIndex = 0;
while (ds.next()) {
Row row = ds.getRow();
if (row instanceof UpdateableRow) {
UpdateableRow rowCrud = (UpdateableRow)row;

rowCrud.setValue("active", false);
dataContextCrud.merge(rowCrud);

if (delIndex++ > 4 ) {
dataContextCrud.delete(rowCrud); // make sure
table stays small :)
}
}
}
}}}

--
Ticket URL: <http://eobjects.org/trac/ticket/858>
eobjects <http://eobjects.org/trac>
The eobjects project management system, based on the trac system.

eobjects

unread,
May 24, 2012, 3:01:53 AM5/24/12
to dataclean...@googlegroups.com
#858: UpdateableRow for crud operations
-------------------------+----------------------------
Reporter: w.cazander | Owner:
Type: enhancement | Status: new
Priority: medium | Milestone: MetaModel 3.0
Component: MetaModel | Resolution:
Keywords: |
-------------------------+----------------------------
Influenced classes:
org.eobjects.metamodel.data.Row

-------------------------+----------------------------

Comment (by kasper):

I am affraid I dont think this is a viable design. There is no possibility
to demarcate transactions or to even ensure synchronization and race-
conditions when doing multiple disparate updates like this. I believe that
our current approach with the UpdateScript handles this much better.

While designing the executeUpdate(...) method this was actually something
that was thought quite a lot about. See http://kasper.eobjects.org/2011/07
/proposal-for-writing-data-in-metamodel.html

But one compromise might be that we created a few simple out-of-the-box
UpdateScript implementations that you could easily use in case you just
wanted to eg. insert a single record:

For instance, this naive implementation:
{{{
public class InsertRow implements UpdateScript {

private final Row _row;

public InsertRow(Row row) {
_row = row;
}

@Override
public void run(UpdateCallback callback) {
callback.insertInto(row.getValue(0).getColumn().getTable()).like(_row).execute();
}
}
}}}

... and this consuming code:

{{{
UpdateableDataContext dc = ...
Row row = ...
dc.executeUpdate(new InsertRow(row));
}}}

--
Ticket URL: <http://eobjects.org/trac/ticket/858#comment:1>

eobjects

unread,
May 24, 2012, 6:30:05 PM5/24/12
to dataclean...@googlegroups.com
#858: UpdateableRow for crud operations
-------------------------+----------------------------
Reporter: w.cazander | Owner:
Type: enhancement | Status: new
Priority: medium | Milestone: MetaModel 3.0
Component: MetaModel | Resolution:
Keywords: |
-------------------------+----------------------------
Influenced classes:
org.eobjects.metamodel.data.Row

-------------------------+----------------------------

Comment (by w.cazander):

Please note that this design is also working implementation where all crud
functions are
delegated to an UpdateScript. So all sync stuff is done by
UpdateableDataContext impl.
Refactored a bit more so integration with current DataContexts should be
easy.

Auto crud support limitations:
- needs query with one FromItem,else falls back to DataSet<Row> result.
- needs table with one or more primary keys, else throws exception.

MM Todos;
- redo AbstractCrudDataContext.queryWhereBuilder* methods to cleaner code
- use correct api to detect selectCount in
AbstractCrudDataContext.executeQueryWrapDataSet
- Add slf4j loggers
- Update Row interface see UpdateableRow and AbstractUpdateableRow.
- Fix table.getPrimaryKeys() see
CrudDataContextImpl.getPrimaryKeysForTable

Also added working unit test to the code to see it in action.

--
Ticket URL: <http://eobjects.org/trac/ticket/858#comment:2>

eobjects

unread,
May 24, 2012, 6:33:42 PM5/24/12
to dataclean...@googlegroups.com
#858: UpdateableRow for crud operations
-------------------------+----------------------------
Reporter: w.cazander | Owner:
Type: enhancement | Status: new
Priority: medium | Milestone: MetaModel 3.0
Component: MetaModel | Resolution:
Keywords: |
-------------------------+----------------------------
Influenced classes:
org.eobjects.metamodel.data.Row

-------------------------+----------------------------

Comment (by w.cazander):

Examples;

// Level 1 integration let the crud impl do all work on
UpdateableDataContext
{{{
UpdateableDataContext dataContext = new CsvDataContext(testFile);
CrudDataContext crudDataContext = new CrudDataContextImpl(dataContext);
}}}

// Level 2 integration no wrapping of DataSet
{{{
class CrudCsvDataContextNoWrap extends CsvDataContext implements
UpdateableRowDataContext {

public DataSet crudExecuteQuery(CrudDataContext
crudDataContext,Query query);
...
// Pass over CrudDataContext until somewhere;
return new CrudCsvDataSet( ... , crudDataContext);
}

public InitFromBuilder crudCreateQuery(CrudDataContext
crudDataContext) {
return new InitFromBuilderImpl(crudDataContext);
}
}
class CrudCsvDataSet extends CsvDataSet {
private CrudDataContext cdc = null;
public CrudCsvDataSet( ... , CrudDataContext cdc) {
super ( ... );
this.cdc = cdc;
}
private boolean nextInternal() {
...
_row = cdc.createRow(table); // Was new
DefaultRow(_selectItems, rowValues);
_row.setValue(...);
...
return true;
}
}
}}}

// Level 3 integration full crud support by DataContext
{{{
class CrudCsvDataContextFull /* extends CsvDataContext */ implements
CrudDataContext {
CrudDataContext crudDataContext = null;
public CrudCsvDataContextFull() {
crudDataContext = new CrudDataContextImpl(this);
}

public DataSet executeQuery(Query query);
return new SomeDataSetImpl<UpdateableRow>(query);
}

public InitFromBuilder createQuery() {
return new InitFromBuilderImpl(crudDataContext);
}

public UpdateableRow createRow(Table table) {
crudDataContext.createRow(table); }
public void persist(UpdateableRow row) {
crudDataContext.persist(row); }
public Object merge(UpdateableRow row) { return
crudDataContext.merge(row); }
public void delete(UpdateableRow row) {
crudDataContext.delete(row); }
}
}}}

// Level 4 integration do it yourself crud
{{{
class JpaCrudDataContext implements CrudDataContext,UpdateableDataContext
{
// Map CrudDataContext crud of JPA
// Map UpdateableDataContext to JPA
}
}}}

--
Ticket URL: <http://eobjects.org/trac/ticket/858#comment:3>

eobjects

unread,
Jun 27, 2012, 5:50:19 AM6/27/12
to dataclean...@googlegroups.com
#858: UpdateableRow for crud operations
-------------------------+----------------------------
Reporter: w.cazander | Owner:
Type: enhancement | Status: new
Priority: medium | Milestone: MetaModel X.0
Component: MetaModel | Resolution:
Keywords: |
-------------------------+----------------------------
Influenced classes:
org.eobjects.metamodel.data.Row

-------------------------+----------------------------
Changes (by kasper):

* milestone: MetaModel 3.0 => MetaModel X.0


Comment:

Batch moving issues to version X.0 for further release planning.

--
Ticket URL: <http://eobjects.org/trac/ticket/858#comment:4>

Reply all
Reply to author
Forward
0 new messages