SitePoint Sponsor

User Tag List

Page 2 of 5 FirstFirst 12345 LastLast
Results 26 to 50 of 110
  1. #26
    SitePoint Addict
    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.

  2. #27
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tanus
    Brenden: I'm interested to see how you're using XSLT to create the business objects.
    This is pretty basic but should get you started. You need php5 for the code below to work. Heres the php:
    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); 
    The class_map.xml file needs to look something like this:
    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
    You can add more classes, or add more attributes but that is what the basic xml file needs to look like.

    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">&lt;?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>
    ?&gt;
    </xsl:template>
    </xsl:stylesheet>
    I dont know what this does to line endings or whatever but thats what Ive been using. (If anyone cleans that up let me know please ).

    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; }
        

    You can add all kinds of things from here like lazy loading associations, add*() function etc.

  3. #28
    SitePoint Addict
    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

  4. #29
    SitePoint Enthusiast
    Join Date
    Apr 2004
    Location
    US
    Posts
    51
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Brenden Vickery
    My current method for data access is similar to jdo (arborint may not be happy ). I pass an object I call PHPDataMapper ($pdm) through my controller like most people pass a db object. There is a single data mapper for all objects, instead of 1 mapper for each object.
    Can you show the detail implementation of PHPDataMapper? Im really interested to see how the whole things fit together.

    An example script with a actual "Object" <> "Mapper" would be every nice.

    Thanks for your help

  5. #30
    SitePoint Enthusiast hantu's Avatar
    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>
    Say you want the products bought by someone ordered by name:

    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); 
    The generated SQL would look like the following:

    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!

  6. #31
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Brenden Vickery
    A problem I have had with using a active record or mapper that is hand coded is that it becomes very unwieldily.

    Lets say we have a active record with this interface:
    PHP Code:
    class Customer {
        
    // all setters / getters
        
    function findAll();
        function 
    findAllWithLastNameLike($lastname);
        function 
    findById($id);

    Then when we are optimising SQL we find that we use findAllWithLastNameLike on 3 pages. One where we need all the customers data, one where we only need the firstname and lastname and one where we need the firstname, lastname and id. So we change the interface to look like this:
    PHP Code:
    class Customer {
        
    // all setters / getters
        
    function findAll();
        function 
    findAllWithLastNameLike($lastname);
        function 
    findAllWithLastNameLikeOnlyFirstLast($lastname);
        function 
    findAllWithLastNameLikeOnlyFirstLastId($lastname);
        function 
    findById($id);

    Whenever I see code like this I have to ask the question "Why are you guys making life difficult for yourselves?" Rather than trying to hard-code a separate function that will deal with a specific set of selection criteria why don't you adopt a generic approach with a single
    PHP Code:
    $fieldarray $object->getData($where); 
    function. The $where argument is a string that can be used as the WHERE clause in an sql SELECT statement, so it can contain as many or as few parts as you wish. So regardless of what you want inside your WHERE clause you never have to create an alternative to the getdata() method.

    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 dataMappers - I don't use them. Basic information is held within each business object, but passed to a DAO when communication with the physical database is required.

    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.

  7. #32
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Tony Marston
    Whenever I see code like this I have to ask the question "Why are you guys making life difficult for yourselves?"
    There are plenty of occasions where this is easier. Either the methods wrap very simple solutions, so that hand coding is sufficient, or they mask a complex problem such as non-SQL data, non-isomorphic schema (e.g. group bys), highly optimised queries or non normalised data. They are just the ones I can think of off the top of my head. I bet there are more.

    Quote Originally Posted by Tony Marston
    Rather than trying to hard-code a separate function that will deal with a specific set of selection criteria why don't you adopt a generic approach
    Yes.

    Quote Originally Posted by Tony Marston
    with a single
    PHP Code:
    $fieldarray $object->getData($where); 
    function.
    No. The column names, and with it the schema, are bleeding upwards and destroying the layering. A minor concern for one object for each row, a big headache for fetching collections and other relationships (e.g. ForeignKeyMapping). It's also harder to unit test as a result.

    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, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  8. #33
    SitePoint Enthusiast hantu's Avatar
    Join Date
    Oct 2004
    Location
    Berlin
    Posts
    54
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tony Marston
    Whenever I see code like this I have to ask the question "Why are you guys making life difficult for yourselves?" Rather than trying to hard-code a separate function that will deal with a specific set of selection criteria why don't you adopt a generic approach with a single
    PHP Code:
    $fieldarray $object->getData($where); 
    function. The $where argument is a string that can be used as the WHERE clause in an sql SELECT statement, so it can contain as many or as few parts as you wish. So regardless of what you want inside your WHERE clause you never have to create an alternative to the getdata() method.
    I don't think that's making life more difficult

    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.

  9. #34
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    There are plenty of occasions where this is easier. Either the methods wrap very simple solutions, so that hand coding is sufficient, or they mask a complex problem such as non-SQL data, non-isomorphic schema (e.g. group bys), highly optimised queries or non normalised data. They are just the ones I can think of off the top of my head. I bet there are more.
    I do not think it is easier to code additional functions for different types of SELECT if your infrastructure already contains a single generic mechanism that will already cater for all possibilities. As to customising the SELECT statement for particular situations I solved that problem several years ago. If you look at the sql manual you will see that the SELECT statement has several clauses. If you define each of these fragments as a separate variable within the class these can be assembled by the DAO into a complete query, as in:
    PHP Code:
    $query "SELECT $select_str FROM $from_str $where_str $group_str $having_str $sort_str $limit_str"
    The presentation layer component (page controller) may supply whatever values for each fragment it wishes to the business layer component (business object) which may or may not adjust the values before passing them to the DAO for final assembly and execution.

    Quote Originally Posted by lastcraft
    Quote Originally Posted by TonyMarston
    ... with a single function:
    PHP Code:
    $fieldarray $object->getData($where); 
    No. The column names, and with it the schema, are bleeding upwards and destroying the layering. A minor concern for one object for each row, a big headache for fetching collections and other relationships (e.g. ForeignKeyMapping). It's also harder to unit test as a result.
    I do not recognise this concept called "bleeding upwards", so I ignore it. It certainly does not destroy my layering as my infrastructure is based on the 3-Tier architecture which I have successfully implemented in more than one language. Each layer (or tier) does exactly what it is supposed to, so there is no problem with any sort of bleeding.

    Quote Originally Posted by lastcraft
    A DataMapper is a full on solution and one not to be taken 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.
    I do not need a separate dataMapper to go with each business object as I successfully combine the two into a single class/object. This keeps all the informaton about an entity (including information on its data structure) in a single class which is what encapsulation is supposed to be about.

    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.

  10. #35
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by hantu
    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
    See my previous reply in which I indicate how the sql fragments are defined within the presentation layer before they are passed through the business layer, then to the DAO for final assembly and execution. All without a dataMapper.

    Quote Originally Posted by hantu
    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
    Conditions may be hard-coded, or they may be supplied at run time from user input, or they may be inserted into the sql fragment by code within the business object. All these variations still do not require more than a single generic getdata() method (at least in my infrastructure they don't).

    Quote Originally Posted by hantu
    c) maybe you want an instance of a certain persistable object as result fo your query, not just an array of fields.
    Maybe, but the point under discussion is creating functions to retrieve data under different circumstances. Doing a retrieve without expecting data to be returned is another topic.

  11. #36
    Non-Member
    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?

  12. #37
    SitePoint Enthusiast hantu's Avatar
    Join Date
    Oct 2004
    Location
    Berlin
    Posts
    54
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tony Marston
    See my previous reply in which I indicate how the sql fragments are defined within the presentation layer before they are passed through the business layer, then to the DAO for final assembly and execution. All without a dataMapper.
    It definitely breaks layering and separation of concerns when the presentation layer cares for generating SQL. In my eyes, in an efficient design the presentation layer shouldn't even know the data is coming from an RDBMS.



    Quote Originally Posted by Tony Marston
    Conditions may be hard-coded, or they may be supplied at run time from user input, or they may be inserted into the sql fragment by code witin the business object. All these variations still do not require more than a single generic getdata() method (at least in my infrastructure they don't).
    They do not require more than a single generic getdata() and a hell a lot of typing. Sorry for me becoming sarcastic.

    Quote Originally Posted by Tony Marston
    Doing a retrieve without expecting data to be returned is another topic.
    ??? I stated I want an object as result of my query ...

  13. #38
    Non-Member
    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.
    You are correct - I had an uncontrollable fit of laughter when I read that piece Tony posted

  14. #39
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tony Marston
    Whenever I see code like this I have to ask the question "Why are you guys making life difficult for yourselves?" Rather than trying to hard-code a separate function that will deal with a specific set of selection criteria why don't you adopt a generic approach with a single
    PHP Code:
    $fieldarray $object->getData($where); 
    function. The $where argument is a string that can be used as the WHERE clause in an sql SELECT statement, so it can contain as many or as few parts as you wish. So regardless of what you want inside your WHERE clause you never have to create an alternative to the getdata() method.
    ...
    Hey Tony,

    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.

    Quote Originally Posted by Tony Marston
    I do not recognise this concept called "bleeding upwards", so I ignore it.

  15. #40
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Tony Marston
    The presentation layer component (page controller) may supply whatever values for each fragment it wishes to the business layer component (business object) which may or may not adjust the values before passing them to the DAO for final assembly and execution.
    Great. So the presentation layer has to construct SQL statements. That's one tier.

    Quote Originally Posted by Tony Marston
    I do not recognise this concept called "bleeding upwards", so I ignore it. It certainly does not destroy my layering as my infrastructure is based on the 3-Tier architecture which I have successfully implemented in more than one language.
    This choice juxtaposition just about sums it up. I know better than to bother to explain anything to you because you will just come back with the same broken assertions. Your claim for three tier is utterly bogus.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  16. #41
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    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.
    None of my objects has knowledge of the layer above it. It receives a request and generates a response. Thus a business object may be called from a controller or another business object. It does not matter which.

    Quote Originally Posted by Dr Livingston
    Alas, you are ignoring this. What arrogance. What stupidity. Ahem.
    So I am arrogant just because I refuse to accept your interpretation? What makes you think that your interpretation is the only true interpretation? Is it not you who is being arrogant?

    Quote Originally Posted by Dr Livingston
    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.
    No, the people here are not trying to help out, they are trying to enforce their opinion of what is right and wrong and utterly refuse to accept any alternative opinions.

    Quote Originally Posted by Dr Livingston
    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?
    Yes, I do know what I am talking about, but do you? Can you explain in words of one syllable exactly how my approach breaks this "bleeding" rule between the layers?

    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.
    If he says so, then who are you to argue?

  17. #42
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by hantu
    It definitely breaks layering and separation of concerns when the presentation layer cares for generating SQL. In my eyes, in an efficient design the presentation layer shouldn't even know the data is coming from an RDBMS.
    The presentation layer does not generate SQL. It contains fragments of SQL which are passed to the business layer where they may or may not be massaged. The business layer then passes these fragments to the data access layer where they are assembled into a complete SQL query and then executed.

    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.

  18. #43
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Great. So the presentation layer has to construct SQL statements. That's one tier.
    Wrong again. The presentation layer does not CONSTRUCT sql statements, it merely identifies fragments of sql statements which are passed through the business layer to the data access layer. It is only in the DAO that a complete SQL query is assembled and executed. This conforms to the principles of the 3-tier architecture.

    Quote Originally Posted by lastcraft
    This choice juxtaposition just about sums it up. I know better than to bother to explain anything to you because you will just come back with the same broken assertions. Your claim for three tier is utterly bogus.
    I'm afraid that it is YOUR interpretation of the principles behind the 3-tier architecture which is utterly bogus. You invent rules that do not exist, then you have the arrogance to me that I am wrong.

  19. #44
    SitePoint Enthusiast
    Join Date
    Apr 2004
    Location
    US
    Posts
    51
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    cum down guys

  20. #45
    Node mutilating coot timnz's Avatar
    Join Date
    Feb 2001
    Location
    New Zealand
    Posts
    516
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tony Marston
    PHP Code:
    $query "SELECT $select_str FROM $from_str $where_str $group_str $having_str $sort_str $limit_str"
    I know your code snippet may be just that, an example, and therefore not complete and I've probably missed how you do this in the course of the discussion, or it may not even be covered in this discussion, but is it possible using the technique you have developed to generate SQL with JOINs? Around 90% of the queries in the application I maintain have a couple of JOINs and around 5% have conditional logic inside the query, such as IFs and CASEs. If this is a requirement can it be fulfilled using your technique?

    Quote Originally Posted by Tony Marston
    I do not recognise this concept called "bleeding upwards", so I ignore it.
    Maybe ask for someone to elaborate then?

    Quote Originally Posted by Tony Marston
    I do not need a separate dataMapper to go with each business object as I successfully combine the two into a single class/object. This keeps all the informaton about an entity (including information on its data structure) in a single class which is what encapsulation is supposed to be about.
    So perhaps the crux is it seems some people think an entity should not contain information on its data structure, whereas you believe it should.

    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 the smilies look like they say "fag!"?
    Oh no! the coots are eating my nodes!

  21. #46
    SitePoint Addict
    Join Date
    Oct 2004
    Location
    Sutton, Surrey
    Posts
    259
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by timnz
    ...is it possible using the technique you have developed to generate SQL with JOINs? Around 90% of the queries in the application I maintain have a couple of JOINs and around 5% have conditional logic inside the query, such as IFs and CASEs. If this is a requirement can it be fulfilled using your technique?
    Yes, definitely. You can put whatever code you like into these fragments, including JOINs with other tables. The only condition is that when the DAO assembles a complete SQL query from these fragments that the end result is a valid query.

    Quote Originally Posted by timnz
    Quote Originally Posted by Tony Marston
    I do not need a separate dataMapper to go with each business object as I successfully combine the two into a single class/object. This keeps all the informaton about an entity (including information on its data structure) in a single class which is what encapsulation is supposed to be about.
    So perhaps the crux is it seems some people think an entity should not contain information on its data structure, whereas you believe it should.
    When I create a class for an entity this class contains all the information, including business rules, which are relevant to this entity. Part of this information is what I call a $fieldspec array which identifies the names of the columns which exist in the table, and which of those columns constitute the primary key. This array is passed to the DAO along with a separate data array (usually the $_POST array) so that the DAO can construct the SQL query which is relevant for that operation on that table.

    Quote Originally Posted by timnz
    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.
    You have hit the nail on the head! They think that by having such information inside a business object that I am not "achieving the correct separation of concerns", but their understanding of what this means is at total variance with my own. I use the term "separation of responsibilities" (not "concerns") to mean the following:
    • 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?

  22. #47
    SitePoint Enthusiast
    Join Date
    Nov 2004
    Location
    Arizona, USA
    Posts
    94
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tony Marston
    How anybody can become confused over such simple logic is beyond me. Are they born like it, or do they take special lessons?


    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.

  23. #48
    SitePoint Zealot
    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?

  24. #49
    Non-Member
    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.
    I'd beg to differ; You have SQL within the Presentation layer which actually in fact belongs within the Model layer to my mind of understand MVC - or nTier for that matter

    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.
    Yer, I'm kind of finding it extremely difficult to find any sense in replying to Tony's posts as well now, the lad just doesn't listen; It's like he knows everything there is to know, and personally I cannot be doing with people who are ba' heeded

  25. #50
    SitePoint Wizard
    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •