SitePoint Sponsor |
|
User Tag List
Results 26 to 50 of 110
-
Oct 8, 2004, 17:59 #26
- Join Date
- Apr 2004
- Location
- Melbourne
- Posts
- 362
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
sike: I'd be very interested to see the xmi reader, at the moment I'm manually writing the xml description files for my business objects, and it's the only tedious part of the developing.
Brenden: I'm interested to see how you're using XSLT to create the business objects. At the moment things follow a rough timeline as
- Upload zip containing xml descriptor, php base class, any additional classes (eg specialised view / edit / admin pages).
- Read XML descriptor to discover any requirements (ie an entitywikipage requires that a certain version of entitywebpage already be installed because it inherits from it), and to discover what properties it contains. These properties are the saved to the database. Currently, at this point, the xml file becomes redundant and could be deleted
- To create the business object, I call 'new businessobjecttype()'. In the object's constructor, all the property definitions for that object's type are read in from the database, and a property object created for them. These property objects are then saved in a $properties array, indexed by the property name. I then use __set and __get for accessing the properties.
What I'm thinking is that it might be possible that instead of the need to read the information about the properties from the database, I could use XSLT to create all the property objects. Do you have any code you're interested in sharing?
And that point you make about not needing to use only ORM is very important; I prefer it when relating objects because it simplifies the whole process (and I'm willing to take the small performance hit). Sometimes though you just need the raw SQL power and I'll use that if necessary; however, it's not a core part of the system.
-
Oct 10, 2004, 17:45 #27
- Join Date
- May 2003
- Location
- Calgary, Alberta, Canada
- Posts
- 275
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Tanus
PHP Code:// Change this to your class map file's location
$classMap = './examples/class_map.xml';
$xsl = new DOMDocument();
$xsl->load(dirname(__FILE__) .
DIRECTORY_SEPARATOR .
'or_mapping.xsl');
$xsltp = new XSLTProcessor();
$xsltp->importStyleSheet($xsl);
$xml = new DOMDocument();
$xml->load($classMap);
$file = $xsltp->transformToXML($xml);
highlight_string($file);
PHP Code:<orm>
<class name="Team">
<field name="id" />
<field name="name" />
<field name="city" />
</class>
<class name="Player">
<field name="id" />
<field name="name" />
<field name="team" />
</class>
</orm>
The or_mapping.xsl file looks like this:
PHP Code:<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" />
<xsl:template match="/orm"><?php
<xsl:for-each select="class">
class <xsl:value-of select="@name"/> {
<xsl:for-each select="field">private $<xsl:value-of select="@name" />;
</xsl:for-each>
<xsl:for-each select="field">public function set<xsl:value-of select="translate(substring(@name, 1, 1), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ')" /><xsl:value-of select="substring(@name, 2, string-length(@name))" />($<xsl:value-of select="@name" />) { $this-><xsl:value-of select="@name" /> = $<xsl:value-of select="@name" />; }
</xsl:for-each>
<xsl:for-each select="field">public function get<xsl:value-of select="translate(substring(@name, 1, 1), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ')" /><xsl:value-of select="substring(@name, 2, string-length(@name))" />() { return $this-><xsl:value-of select="@name" />; }
</xsl:for-each>
}
</xsl:for-each>
?>
</xsl:template>
</xsl:stylesheet>).
The output should look like this:
PHP Code:class Team {
private $id;
private $name;
private $city;
public function setId($id) { $this->id = $id; }
public function setName($name) { $this->name = $name; }
public function setCity($city) { $this->city = $city; }
public function getId() { return $this->id; }
public function getName() { return $this->name; }
public function getCity() { return $this->city; }
}
class Player {
private $id;
private $name;
private $team;
public function setId($id) { $this->id = $id; }
public function setName($name) { $this->name = $name; }
public function setTeam($team) { $this->team = $team; }
public function getId() { return $this->id; }
public function getName() { return $this->name; }
public function getTeam() { return $this->team; }
}
-
Oct 10, 2004, 20:12 #28
- Join Date
- Apr 2004
- Location
- Melbourne
- Posts
- 362
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Okay, thanks, I'll see if I can make it fit. What I might do is instead of generating a class file, have it generate object creation statements that I then eval(). Thanks for the ideas though
-
Jan 23, 2005, 00:29 #29
- Join Date
- Apr 2004
- Location
- US
- Posts
- 51
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Brenden Vickery
An example script with a actual "Object" <> "Mapper" would be every nice.
Thanks for your help
-
Jan 23, 2005, 03:52 #30
- Join Date
- Oct 2004
- Location
- Berlin
- Posts
- 54
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Hi there guys, another one of this wonderful data access strategy threads
In the last discussions I stated that I'd like to have an O/R-mapper that doesn't use code generation and is non-intrusive (which means the persistable domain objects don't need to inherit from a certain class). I'm still developing such a thing and have finished about 40% maybe
I'm parsing an XML-File similar to the ones shown above, populating "ClassDescriptor", "FieldDescriptor" and "ReferenceDescriptor" objects from this and save them serialized on the disk. The XML-File will only be parsed again, when changes occured and the serialized data is lazy loaded by my application.
I'm quite inspired by apache OJB and try to provide a similar API. That means your persistable objects are very simple lightweight classes with only properties and setter/getter methods.
Queries will be done using a Query Object combined with Criteria objects similar to propels. The required joins will be generated automatically (including m:n associations)
a short example: a product can be bought by many buyers:
Code:<mapping> <class name="Product" table="product"> <field name="Id" column="id" type="integer" primaryKey="true" /> <field name="Name" column="name" type="string" required="true" /> <field name="Price" column="price" type="double" /> <many2ManyReference name="buyers" targetClass="Buyer" indirectionTable="product2buyer" indirectionColumnForThis="p_id" indirectionColumnForTarget="b_id" /> </class> <class name="Buyer" table="buyer"> <field name="Id" column="id" type="integer" primaryKey="true" /> <field name="Firstname" column="firstname" type="string" /> <field name="Lastname" column="lastname" type="string" required="true" /> <field name="LastLogin" column="lastlogin" type="date" /> </class> </mapping>
PHP Code:
$criteria = new Criteria();
$criteria->addEqualTo('Buyer.Firstname', 'Franz');
$criteria->addEqualTo('Buyer.Lastname', 'Schwanz');
$query = new QueryByCriteria('Product', $criteria);
$query->addOrderByAscending('Name');
$broker = new PersistenceBroker();
$products = $broker->getByQuery($query);
SELECT A0.* FROM prd A0
JOIN product2buyer B0 ON A0.id = B0.p_id
JOIN buyer A1 ON A1.id = B0.b_id
WHERE A1.firstname = 'Franz' AND A1.lastname = 'Schwanz'
ORDER BY A0.name ASC
I hope my approach has become clear. I'd appreciate any comments, suggestions, critic. If my app will be finished one day (and be performant enough) I'd like to release it licensed by LGPL. If anybody would like to help developing, I'd appreciate this!
-
Jan 24, 2005, 08:05 #31
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Brenden Vickery
PHP Code:$fieldarray = $object->getData($where);
By default this will select all columns from the current table, but if you want something different then supply a value such as:
PHP Code:$object->sql_select = 'column1, column2';
When it comes to data access objects - I have one for the whole application, not one per database table. How is this possible? Because my DAO is not coded with any database, table or column names. These are all supplied by the calling object at run time. The DAO will then use whatever information it is given to construct an sql query, then call the relevant API for its designated DBMS.
Note that I have a separate DAO for each DBMS, so I can switch from one DBMS to another simply by switching my DAO.Last edited by Tony Marston; Jan 25, 2005 at 11:48.
-
Jan 24, 2005, 08:39 #32
- Join Date
- Apr 2003
- Location
- London
- Posts
- 2,423
- Mentioned
- 2 Post(s)
- Tagged
- 0 Thread(s)
Hi...
Originally Posted by Tony Marston
Originally Posted by Tony Marston
Originally Posted by Tony Marston
A DataMapper is a full on solution and one not to be taked lightly. Not least because you will need a new class for every business object to do the mapping. If you want the most flexible solution (it offers complete data source independence), and you are willing to resort to tricks like reflection and code generation to speed up development, then it is the Rolls-Royce answer.
Depending on the problem there could be much simpler answers, but the discussion seems to be too abstract right now for me to say.
yours, MarcusMarcus Baker
Testing: SimpleTest, Cgreen, Fakemail
Other: Phemto dependency injector
Books: PHP in Action, 97 things
-
Jan 24, 2005, 08:46 #33
- Join Date
- Oct 2004
- Location
- Berlin
- Posts
- 54
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Tony Marston
Here's what I see as disadvantages of your solution
a) with a query object/criteria approach joins are generated as needed by the mapper, I don't see how you would add a join only within a where clause
b) maybe you don't want to hardcode your query but generate it based on certain conditions, criteria objects can easily be generated but with valid SQL that's more difficult
c) maybe you want an instance of a certain persistable object as result fo your query, not just an array of fields.
-
Jan 24, 2005, 12:58 #34
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by lastcraft
PHP Code:$query = "SELECT $select_str FROM $from_str $where_str $group_str $having_str $sort_str $limit_str";
Originally Posted by lastcraft
Originally Posted by lastcraft
Before you jump on me and say that I am not achieving the "correct separation of concerns" let me point out that although each business object holds information about the data structure it does nothing with it - it is passed to the DAO which is the only object in the entire application which communicates with the database. Thus my business object holds all information about an entity (thus satisfying the principle of encapsulation), but it is the DAO which is responsible for using this information to communicate with the database. This is my interpretation of what "separation of responsibilities" actually means.Last edited by Tony Marston; Jan 25, 2005 at 12:04.
-
Jan 24, 2005, 13:08 #35
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by hantu
Originally Posted by hantu
Originally Posted by hantu
Last edited by Tony Marston; Jan 25, 2005 at 12:05.
-
Jan 24, 2005, 13:16 #36
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
The concept of 'bleeding upwards' is not really a concept but a term to refer to one layer knowing about the layer above it; and as pointed out by Lastcraft this will definitely without any doubt at all, break layering - this is what your application layer(s) does and it's been pointed out to you.
Alas, you are ignoring this. What arrogance. What stupidity. Ahem.
You seam to ignore a lot of thought and advice pointed out to you by sitepoint members; they are trying to help you but you lack the understanding as you are not willing to learn more.
Btw, in relation to layering, any given layer (regardless of it's disposition or task) should only ever know of the layer(s) below it, and not never know what's above it; if you understand this, then maybe you can explain as to why this is?
Just so we all know you know what your talking about?
-
Jan 24, 2005, 14:31 #37
- Join Date
- Oct 2004
- Location
- Berlin
- Posts
- 54
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Tony Marston
Originally Posted by Tony Marston
Originally Posted by Tony Marston
-
Jan 24, 2005, 14:52 #38
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
In my eyes, in an efficient design the presentation layer shouldn't even know the data is coming from an RDBMS.
-
Jan 24, 2005, 16:25 #39
- Join Date
- May 2003
- Location
- Calgary, Alberta, Canada
- Posts
- 275
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Tony Marston
I think you've missed the point. "Hard-coded" behind that function may be a generic approach similar to yours. The point is, it doesnt matter as long as the parameters to the function are the same and the the return value is what is expected.
By putting the generic approach inside the function you start to see spots to refactor and your code becomes cleaner.
Originally Posted by Tony Marston
-
Jan 24, 2005, 16:34 #40
- Join Date
- Apr 2003
- Location
- London
- Posts
- 2,423
- Mentioned
- 2 Post(s)
- Tagged
- 0 Thread(s)
Hi...
Originally Posted by Tony Marston
Originally Posted by Tony Marston
yours, MarcusMarcus Baker
Testing: SimpleTest, Cgreen, Fakemail
Other: Phemto dependency injector
Books: PHP in Action, 97 things
-
Jan 25, 2005, 02:20 #41
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Dr Livingston
Originally Posted by Dr Livingston
Originally Posted by Dr Livingston
Originally Posted by Dr Livingston
Just because objects in the presentation layer, business layer and data access layer each have knowledge of database column names does not break any rules. Even the guru most often quoted in this forum acknlowledges this fact:Martin Fowler in PoEAA
Layers encapsulate some, but not all, things well. As a result you sometimes get cascading changes. The classic example of this in a layered enterprise application is adding a field that needs to display on the UI, must be in the database, and thus must be added to every layer in between.
-
Jan 25, 2005, 02:35 #42
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by hantu
As a complete SQL query is only assembled and executed within my DAO I do not consider that I am breaking any rules.
Your interpretation of the requirements of the presentation layer are incorrect. According to every book or article I have read on the subject the ONLY requirement is that the presentation layer must not communicate directly with the database. It passes a request to the business layer which in turn passes a request to the data acess layer. The response is then passed back through the business layer to the presentation layer. It is only the DAO that can have any type of communication with the database. The passing of sql fragments between the various layers does not constitute database access, therefore I am not breaking the principles of the 3-tier architecture.
-
Jan 25, 2005, 02:46 #43
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by lastcraft
Originally Posted by lastcraft
-
Jan 25, 2005, 03:48 #44
- Join Date
- Apr 2004
- Location
- US
- Posts
- 51
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
cum down guys
-
Jan 25, 2005, 04:12 #45
- Join Date
- Feb 2001
- Location
- New Zealand
- Posts
- 516
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Tony Marston
Originally Posted by Tony Marston
Originally Posted by Tony Marston
I don't think (excuse me if I'm speaking out of place here) those who believe it should not contain it, say that what you're doing isn't "encapsulation". I don't think that's the argument against your idea, although they may not agree with your expansion of the term encapsulation to cover that as well.
They think that the entity should not contain the data structure information EVEN if it does not use it itself, the even being the key point.
I feel Swiss I'm trying to be so neutral
Off Topic:
Is it just me or at a cursory glance do thesmilies look like they say "fag!"?
Oh no! the coots are eating my nodes!
-
Jan 25, 2005, 06:57 #46
- Join Date
- Oct 2004
- Location
- Sutton, Surrey
- Posts
- 259
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by timnz
Originally Posted by timnz
Originally Posted by timnz
- The presentation layer is responsible for all dialog with the user.
- The business layer is responsible for all business rules.
- The data access layer is responsible for all communication with the database.
So even though my business object contains some information about the structure of the associated database table this is totally irrelevant as it is the DAO which is responsible for using this information to communicate with the database. Responsibility means doing something with the information, not simply holding it for subsequent transfer to another object.
In my view I do not need to take this small amount of information out of my business object and hold it anywhere else as there is no justification. On the other hand, if I did move it to a separate object I would be breaking the principle of encapsulation as I would be holding information about a business entity in TWO places instead of ONE.
How anybody can become confused over such simple logic is beyond me. Are they born like it, or do they take special lessons?Last edited by Tony Marston; Jan 25, 2005 at 12:09.
-
Jan 25, 2005, 08:22 #47
- Join Date
- Nov 2004
- Location
- Arizona, USA
- Posts
- 94
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Originally Posted by Tony Marston
I'm new to posting on these forums, but have lurked here for quite some time and am very familiar with your act. You have the uncanny ability to bring down the quality of an entire forum thread with this type of garbage (not to mention the shameless, non-stop pimping of your website).
Consider yourself reported.Bryan Dunlap - http://www.bryandunlap.com
-
Jan 25, 2005, 08:57 #48
- Join Date
- Jun 2004
- Location
- Bogota
- Posts
- 101
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Q. Do you declare these parts of the SQL in your view? I mean, the $where part that you pass down to the data access layer.
If I have wings, why am I walking?
-
Jan 25, 2005, 10:35 #49
- Join Date
- Jan 2003
- Posts
- 5,748
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
None of my objects has knowledge of the layer above it.
Also I might add that I personally am not arrogant; I read the posts on these forums and I actually learn from them. I like to think that folks are helping me out, and I am indeed trying to help you out as well but you are ignoring the advice.
If my advice is wrong, then sure enough someone will point that out, and again I'll take note of my error, but I think your layering is wrong, and a few other members think your layering is wrong as well, so surely we cannot all be wrong huh?
Are you going to be arrogant enough to say we are eh? Your SQL is in the wrong place for the love of God, like how many different ways can we put that to you? Doesn't matter is it's fragments of SQL or whatever, it's still in the wrong place.
For the Martin Fowler quote, that is something I'm not familuar with; maybe you can post the url where the quote is
I know better than to bother to explain anything to you because you will just come back with the same broken assertions.
-
Jan 25, 2005, 11:27 #50
- Join Date
- Oct 2001
- Posts
- 2,686
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
There are some comments here that is really close to get this thread closed. I guess I don't have to point them out for you all. Another incident, event the smallest one, will result in closing.
If you're not adult enough to keep this civilized, then stay out of the discussion!
Bookmarks