row specific class - zend-framework

How do I create a Zend_Db_Table which returns a different class for each row.?
Example
UserTable has id,name and type
Type contains class names (admin,client,etc...)
The classes admin, client are all subclasses of user
If I call fetch I need to get a admin or client object depending on the corresponding value in the db.

class Your_Db_Table_Row extends Zend_Db_Table_Row_Abstract
{
}
class Your_Db_Table extends Zend_Db_Table_Abstract
{
protected $_rowClass = "Your_Db_Table_Row";
}
or
new Your_Db_Table(array("rowClass" => "Your_Db_Table_Row");
So whenever you get a rowset from your table subclass, the rows included in it will be your custom class.
Edit
To get a custom row based on a value, I would say extend the Zend_Db_Table_Rowset_Abstract class instead and override this method:
getRow(int $position, [bool $seek = false])
You'll also need to override the current method and perhaps some of the other SeekableIterator implemetations which actually creates a row class based on the _rowClass property. You might be able to set the _rowClass before current is called based on your data's row type.
You could instantiate a specific class in current and return it based on the type parameter.
Have you though about maybe just using composition instead? Say just passing in data to a new class if it's an admin type or something?

Related

How to make use of the user defined View to pipe data into application with flutter/drift(moor)

I declared some Views following the example in the drift documentation besides database table definitions and managed to go through the generation process. After then I was quite confused as to the usage of the abstract View classes, which I could neither instantiate to make query nor incorporate it into query definitions(get or watch).
abstract class TestingRemoteSignalView extends View {
TestingRemoteSignal get testingRemoteSignal;
Bay get bay;
RemoteSignal get remoteSignal;
Expression<String> get description => bay.name + remoteSignal.signalName;
#override
Query as() {
return select([
testingRemoteSignal.id,
bay.name,
description,
testingRemoteSignal.passed,
testingRemoteSignal.skipped,
testingRemoteSignal.touched,
testingRemoteSignal.memo,
]).from(testingRemoteSignal).join([
innerJoin(bay, testingRemoteSignal.bay.equalsExp(bay.id)),
innerJoin(
remoteSignal, testingRemoteSignal.signal.equalsExp(remoteSignal.id))
]);
}
}
What is the use of these View classes and how to make queries out of them? Maybe something like:
final query = select(TestingRemoteSignalView)..where((t) => t.passed.isEquals(true));
query.watch();
This page in the Drift documentation has a section on views here.
I found this video on Youtube quite helpful as well.
Once you have created your view code as you have in your question, you need to add the view to database definition as follows (from the documentation):
#DriftDatabase(tables: [Todos, Categories], views: [CategoryTodoCount])
class MyDatabase extends _$MyDatabase {
Then you need to delete and rebuild your '.g.dart' file.
You should then be able to access the view in a query like any other table. Here is an example from my own code:
View definition
abstract class FrequencyView extends View {
Frequency get frequency;
Instrument get instrument;
Range get range;
#override
Query as() => select([
frequency.id,
frequency.type,
frequency.start,
frequency.end,
instrument.iname,
range.rname
]).from(frequency).join([
innerJoin(instrument, instrument.id.equalsExp(frequency.instrumentID))
]).join([innerJoin(range, range.id.equalsExp(frequency.rangeID))]);
}
// FrequencyView declared in DraftDatabase declaration below...
#DriftDatabase(tables: [Frequency, Range, Instrument], views: [FrequencyView])
class MyDatabase extends _$MyDatabase {
// we tell the database where to store the data with this constructor
MyDatabase() : super(_openConnection());
// you should bump this number whenever you change or add a table definition.
// Migrations are covered later in the documentation.
#override
int get schemaVersion => 1;
}
As an aside, I had fields with the same name in different tables ('name'), which caused errors in the .g.dart file once I had rebuilt it. I wasn't sure if you can alias column names in a view so I just gave them all unique names.
View select query
import 'package:drift/drift.dart' as drift;
Future<List<FrequencyViewData>> _getFrequencyPlus(MyDatabase db) async {
List<FrequencyViewData> values = await (db.select(db.frequencyView)
..orderBy([(t) => drift.OrderingTerm(expression: t.start)]))
.get();
return values;
}
This query returns a full set of data. I assume you can add "where" clauses to this just like a standard select clause on a single table to get partial returns.

How to use CellTable<T> when T is an interface

in my current project I have to render items in a CellTable received via a RPC call. The columns must be created dynamically and the column types are unknown at compile time.
From the server side, I send a list of the following class to define a row in the table:
public class TableRowDTO implements IsSerializable {
private List<IsTableItemDTO> tableItemDTOs;
public TableRowDTO() {
tableItemDTOs = new ArrayList<IsTableItemDTO>();
}
// getters & setters ...
}
Where each row will contain an item implementing IsTableItemDTO which is a marker interface:
public interface IsTableItemDTO extends IsSerializable {}
Implementing classes depict the actual controls/information to be shown in cells like:
public class TableDateTimeDTO extends IsTableItemDTO {
private Date valueDate;
// ... other fields not necessary for the table
}
Or also:
public class TableCheckBoxDTO extends AbstractTableItemDTO {
private boolean checked;
// ... other fields not necessary for the table
}
And also:
TablePasswordDTO extends AbstractTableItemDTO {
private String valueText;
// ... other fields not necessary for the table
}
Therefore, what I want to do for example in the case I receive a List with {TableCheckBoxDTO, TableDateTimeDTO, TablePasswordDTO} is to render a CellTable with the corresponding widgets.
I've seen this and this, but I don't see how to apply any of the examples to my case especially because I cannot use thigs like Column as I don't have my ContactInfo before hand.
Thanks
You can use the marker interface IsTableItemDTO together with instanceof() and dynamic casts to have a generic Column/Cell.
There are 2 ways:
Create a Composite Cell and add all possible cell types and then display based on what specific sub-type your isTableItemDTO is.
Create a custom cell and render the input (checkbox, text) based on the specific type of your marker interface
I used Jet table (https://code.google.com/p/gwt-jet/) in one of my earlier projects. I believe it has the features you are looking for.

How to solve field wrapping in Entity Framework database-first

When I use database first, after creating the edmx file, all the conceptual models have already been generated. But I want to do some special operations on certain fields. For example, there's a field named 'price'; I want the matching property 'Price' to return double of the 'price'. How can I do that? If I modify the getter in the code, every time I update the model from database, all of the modifications go away.
What's the correct way to do this?
What you can do is create a partial class for entity which contains the Price Property and put a getter like this (A property with double price will be meaningful ),
Public partial class YourEntity{
Public float DoublePrice{
get { return Price*2;}
}
}
Or you can create a class inherited from the entity,
Public partial class Entity:YourEntity{
Public override float Price{
get { return base.Price*2;}
}
}

Wicket - Wrapped collection Model "transformation"

I have a domain object which has a collection of primitive values, which represent the primary keys of another domain object ("Person").
I have a Wicket component that takes IModel<List<Person>>, and allows you to view, remove, and add Persons to the list.
I would like to write a wrapper which implements IModel<List<Person>>, but which is backed by a PropertyModel<List<Long>> from the original domain object.
View-only is easy (Scala syntax for brevity):
class PersonModel(wrappedModel: IModel[List[Long]]) extends LoadableDetachableModel[List[Person]] {
#SpringBean dao: PersonDao =_
def load: List[Person] = {
// Returns a collection of Persons for each id
wrappedModel.getObject().map { id: Long =>
dao.getPerson(id)
}
}
}
But how might I write this to allow for adding and removing from the original List of Longs?
Or is a Model not the best place to do this translation?
Thanks!
You can do something like this:
class PersonModel extends Model<List<Person>> {
private transient List<Person> cache;
private IModel<List<String>> idModel;
public PersonModel( IModel<List<String>> idModel ) {
this.idModel = idModel;
}
public List<Person> getObject() {
if ( cache == null ) {
cache = convertIdsToPersons( idModel.getObject() );
return cache;
}
public void setObject( List<Person> ob ) {
cache = null;
idModel.setObject( convertPersonsToIds( ob ) );
}
}
This isn't very good code but it shows the general idea. One thing you need to consider is how this whole thing will be serialised between requests, you might be better off extending LoadableDetachableModel instead.
Another thing is the cache: it's there to avoid having to convert the list every time getObject() is called within a request. You may or may not need it in practice (depends on a lot of factors, including the speed of the conversion), but if you use it, it means that if something else is modifying the underlying collection, the changes may not be picked up by this model.
I'm not quite sure I understand your question and I don't understand the syntax of Scala.
But, to remove an entity from a list, you can provide a link that simply removes it using your dao. You must be using a repeater to populate your Person list so each repeater entry will have its own Model which can be passed to the deletion link.
Take a look at this Wicket example that uses a link with a repeater to select a contact. You just need to adapt it to delete your Person instead of selecting it.
As for modifying the original list of Longs, you can use the ListView.removeLink() method to get a link component that removes an entry from the backing list.

Get Primary Key out of Zend_Db_Table_Rowset Object

inside of my Zend_Db_Table_Rowset Object i found this:
["_primary:protected"]
... does anybody if theres a way to access this? ... maybe something like
$rowsetObject->getPrimary()
Thanks for your help,
Alex
Zend_Db_Table_Rowset has no property _primary. What you are refering to is either the Zend_Db_Table instance you got the Rowset from or a Zend_Db_Table_Row instance inside the Rowset.
For getting the primary key from a Zend_Db_Table instance you can do:
$tableInstance->info('primary')
For getting the primary key from a Zend_Db_Table_Row instance you can get the table instance and call info() on it:
$rowInstance->getTable()->info('primary')
Note that this will not work when the row is disconnected, because then getTable() will return null.
Or, when using a custom Zend_Db_Table_Row you can add a method that proxies to _getPrimaryKey():
class My_Db_Table_Row extends Zend_Db_Table_Row
{
public function getPrimaryKey()
{
return $this->_getPrimaryKey();
}
}
Since this variable is protected, you can extend Zend_Db_Table_Rowset and define getPrimary() function yourself, e.g.
class My_Zend_Db_Table_Rowset extends Zend_Db_Table_Rowset {
//put your code here
function getPrimary() {
return $this->_primary;
}
}