Yet, another example of, sorry, complete arrogance:
I do not use separate DBMS developers because they will want to follow their own set of stupid rules for designing databases. When a database is being used by MY application then I insist on designing that database according to MY rules.
also
Glen wrote: ps: This is not written out of arrogance and I don’t think I know it better than anyone else. I’m just a student, and also was pondering about a nice oo-approach to php/mysql scripting.
Here’s my advice (for what it’s worth):
Don’t give up your day job.
If you are paying for lessons then ask for your money back.
If you are teaching yourself then you need a new teacher.
If you are reading books then they are the wrong books, or they have some pages missing.
But there is one answer question that really explains the last 400 messages of this thread and explains the “why” of the 9000 LoC class. On this own thread Tony posts the question made by André Næss :
You should try object composition instead of inheritance
There is a very common error which people do the first time they do OO, and that is to overuse inheritance. It’s not that strange really as there’s always a lot of fighting over inheritance. But object composition is a second technique that frequently applies. Where you see only inheritance, I see inheritance and composition.
Which Tony answered, and based on this thread, still defends:
You have totally misunderstood my design as there is no way that I overuse inheritance. All my concrete table classes, and I have hundreds, inherit from a single abstract class. My inheritance hierarchy is only one level deep, so how can this be described as “overuse”?
(…)
In the first place I do not have a large inheritance hierarchy as all my concrete table classes inherit from a single abstract table class, therefore I am not overusing inheritance by any stretch of the imagination. If I don’t have a problem then why do I need a solution?
In the second place I am not going to change a method which is simple and effective for one that introduces another level of complexity for absolutely no discernible benefit. This is another one of those loony OO ideas that I shall consign to the khazi.
My conclusion from your statements is that, if a entity A share some responsibilities with entity B then you put the code in the parent generic entity X, but because this is “related” to the entity itself you place it there and nowhere else. So, which means that the generic entity is responsible for anything that happens one more that one entity. In your example, the GenericTable is responsible for binding the post data, validating, fetching, paging, foreing key validation, transaction, formating, uploading files, translating, holding data, some sql composition, … thus making 232 methods available there:
function Default_Table ()
function array2string ($array)
function cascadeDelete ($where, $parent_table=null)
function cascadeNullify ($update_array, $where)
function changeConfig ($fieldarray)
function checkWorkflow ($where)
function clearEditableData ($fieldarray)
function clearScrollArray ()
function commit ()
function convertTimeZone ($fieldarray, $fieldspec)
function currentOrHistoric ($string, $start_date='start_date', $end_date='end_date')
function customButton ($fieldarray, $button, $postarray, $row=null)
function deleteMultiple ($fieldarray)
function deleteRecord ($fieldarray, $parent_table=null)
function deleteRelations ($fieldarray)
function deleteScrollItem ($index)
function deleteSelection ($selection)
function eraseRecord ($fieldarray)
function eraseRelations ($fieldarray)
function executeQuery ($query)
function fetchRow ($resource)
function fetchRowChild ($row)
function filePickerSelect ($selection)
function fileUpload ($input_name, $temp_file)
function formatData ($fieldarray, &$css_array)
function free_result ($resource)
function &getChildData ()
function getClassName ()
function getColumnNames ($where=null)
function getCount ($where=null)
function getData ($where=null)
function getData_raw ($where=null)
function getData_serial ($where=null, $rdc_limit=null, $rdc_offset=null, $unbuffered=false)
function getDBname ()
function getEnum ($fieldname)
function getErrors ()
function getExpanded ()
function getExtraData ($input, $where=null)
function getFieldArray ()
function getFieldSpec ()
function getFieldSpec_original ()
function getForeignData ($fieldarray)
function getInitialData ($where)
function getInitialDataMultiple ($where)
function getInstruction ()
function getLanguageArray ($id)
function getLanguageEntries ($rows, $parent_data, $fieldlist)
function getLanguageText ($id, $arg1=null, $arg2=null, $arg3=null, $arg4=null, $arg5=null)
function getLastIndex ()
function getLastPage ()
function getLookupData ()
function getMessages ()
function getNodeData ($expanded, $where=null)
function getNumRows ()
function getOrderBy ()
function getOrderBySeq (&$orderby=null, $orderby_seq=null)
function getPageNo ()
function &getParentData ()
function getPkeyArray ($fieldarray=null, $next_task=null)
function getPkeyNames ()
function getPkeyNamesAdjusted ()
function getScrollIndex ()
function getScrollItem (&$index)
function getScrollSize ()
function getSearch ()
function getTableName ()
function getValRep ($item, $where=null, $orderby=null)
function getWhere ($next_task)
function initialise ($where=null, &$selection=null, $search=null)
function initialiseFileDownload ($where)
function initialiseFilePicker ($where, $search=null)
function initialiseFileUpload ($where)
function insertMultiple ($fieldarray)
function insertOrUpdate ($fieldarray)
function insertRecord ($fieldarray)
function multiQuery ($query)
function popupCall (&$popupname, $where, &$script_vars, $fieldarray, &$settings)
function popupReturn ($fieldarray, $return_from, $selection, $popup_offset=null)
function post_fileUpload ($filename, $filesize)
function post_search ($search, $selection)
function reInitialise ($fieldarray, $where)
function reset ($where=null, $keep_orderby=false)
function restart ($return_from, $return_action, $return_string=null)
function rollback ()
function scriptNext ($task_id, $where=null, $selection=null, $task_array=array())
function scriptPrevious ($errors=null, $messages=NULL, $action=NULL, $instruction=NULL)
function selectDB ($dbname)
function setAction ($action)
function setChildData ($data)
function setChildObject (&$childOBJ)
function setCurrentOrHistoric ()
function setDefaultOrderBy ($sql_orderby='')
function setFieldAccess ()
function setFieldArray ($fieldarray, $reset_pageno=true)
function setInstruction ($instruction)
function setLookupData ($input=null)
function setOrderBy ($sql_orderby, $sql_orderby_seq=null, $toggle=true)
function setOrderBySeq ($sql_orderby_seq)
function setPageNo ($pageno=null)
function setParentData ($data)
function setParentObject (&$parentOBJ)
function setRowsPerPage ($rows_per_page)
function setScrollArray ($where)
function setScrollIndex ($index='1')
function setSelectedRows ($select_string, $rows)
function setSqlSearch ($sql_search=null, $save=false)
function setSqlGroupBy ($sql_groupby=null)
function setSqlWhere ($sql_where)
function sqlSelectDefault ()
function sqlSelectInit ()
function startTransaction ()
function unFormatData ($fieldarray)
function unFormatNumber ($fieldarray)
function updateFieldArray ($fieldarray, $postarray)
function updateLinkData ($fieldarray, $postarray)
function updateMultiple ($fieldarray, $postarray=array())
function updateRecord ($fieldarray)
function updateSelection ($selection, $replace)
function validateDelete ($fieldarray, $parent_table=null)
function validateSearch ($fieldarray)
function validateUpdate ($fieldarray)
function _cm_changeConfig ($where, $fieldarray)
function _cm_commonValidation ($fieldarray, $originaldata)
function _cm_customButton ($fieldarray, $button)
function _cm_deleteSelection ($selection)
function _cm_filePickerSelect ($selection)
function _cm_fileUpload ($input_name, $temp_file, $wherearray)
function _cm_filterWhere ($array=null)
function _cm_formatData ($fieldarray, &$css_array)
function _cm_getColumnNames ($fieldarray)
function _cm_getDatabaseLock ()
function _cm_getExtraData ($where, $fieldarray)
function _cm_getForeignData ($fieldarray)
function _cm_getInitialData ($fieldarray)
function _cm_getInitialDataMultiple ($fieldarray)
function _cm_getNodeData ($expanded, $where, $where_array = null)
function _cm_getNodeKeys ($keys)
function _cm_getOrderBy ($orderby)
function _cm_getPkeyNames ($pkey_array, $task_id, $pattern_id)
function _cm_getValRep ($item=null, $where=null, $orderby=null)
function _cm_getWhere ($where, $task_id, $pattern_id)
function _cm_initialise ($where, &$selection, $search)
function _cm_initialiseFileDownload ($fieldarray)
function _cm_initialiseFilePicker ($fieldarray, $search)
function _cm_initialiseFileUpload ($fieldarray)
function _cm_ListView_header ($fieldarray)
function _cm_ListView_print_before ($prev_row, $curr_row)
function _cm_ListView_print_after ($curr_row, $next_row)
function _cm_ListView_total ()
function _cm_output_multi ($name, $fieldarray)
function _cm_popupCall (&$popupname, $where, $fieldarray, &$settings)
function _cm_popupReturn ($fieldarray, $return_from, &$select_array)
function _cm_post_deleteMultiple ($rows)
function _cm_post_deleteRecord ($fieldarray)
function _cm_post_eraseRecord ($fieldarray)
function _cm_post_fetchRow ($fieldarray)
function _cm_post_fileUpload ($filename, $filesize)
function _cm_post_getData ($rows, &$where)
function _cm_post_insertMultiple ($rows)
function _cm_post_insertOrUpdate ($fieldarray, $insert_count, $update_count)
function _cm_post_insertRecord ($fieldarray)
function _cm_post_lastRow ()
function _cm_post_output ($string, $filename)
function _cm_post_popupReturn ($fieldarray, $return_from, $select_array)
function _cm_post_search ($search, $selection)
function _cm_post_updateLinkdata ($rows, $postarray)
function _cm_post_updateMultiple ($rows)
function _cm_post_updateRecord ($fieldarray, $old_data)
function _cm_post_updateSelection ($selection, $replace)
function _cm_pre_cascadeDelete ($fieldarray)
function _cm_pre_deleteMultiple ($rows)
function _cm_pre_deleteRecord ($fieldarray)
function _cm_pre_eraseRecord ($fieldarray)
function _cm_pre_getData ($where, $where_array, $fieldarray=null)
function _cm_pre_insertMultiple ($rows)
function _cm_pre_insertOrUpdate ($rows)
function _cm_pre_insertRecord ($fieldarray)
function _cm_pre_output ($filename)
function _cm_pre_updateLinkdata ($rows, &$postarray)
function _cm_pre_updateMultiple ($rows)
function _cm_pre_updateRecord ($fieldarray)
function _cm_pre_updateSelection ($selection, $replace)
function _cm_reset ($where)
function _cm_restart ($pattern_id, $zone, $return_from, $return_action, $return_string)
function _cm_setJavaScript ($javascript)
function _cm_setScrollArray ($where, $where_array)
function _cm_unFormatData ($fieldarray)
function _cm_updateFieldarray ($fieldarray, $postarray, $rownum)
function _cm_updateSelection ($selection, $replace)
function _cm_validateDelete ($rowdata, $parent_table)
function _cm_validateInsert ($rowdata)
function _cm_validateSearch ($fieldarray)
function _cm_validateUpdate ($fieldarray, $originaldata)
function _ddl_getColumnSpecs ()
function _ddl_showColumns($dbname, $tablename)
function _ddl_showCreateTable ($dbname, $tablename)
function _ddl_showDatabases ($dbprefix)
function _ddl_showTables ($dbname)
function _ddl_showTableKeys ($dbname, $tablename)
function _dml_deleteRecord ($fieldarray)
function _dml_adjustWhere ($string_in)
function _dml_deleteSelection ($selection, $from=null, $using=null, $limit=0)
function _dml_free_result ($resource)
function _dml_getCount ($where)
function _dml_getData ($where, $raw=false)
function _dml_getData_serial ($where=null, $rdc_limit=null, $rdc_offset=null, $unbuffered_query=false)
function _dml_getEnum ($item)
function _dml_insertRecord ($fieldarray)
function _dml_multiQuery ($query)
function _dml_ReadBeforeUpdate ($where, $reuse_previous_select=false)
function _dml_updateRecord ($fieldarray, $oldarray, $where=null)
function _dml_updateSelection ($selection, $replace, $limit=0)
function _examineWorkflow ($input)
function _examineWorkflowInstance ($where)
function _extract_custom_fields ($rowdata)
function _getCustomProcessingObject ()
function &_getDBMSengine ($dbname=null, $unbuffered_query=false)
function _getInitialValues ($task_id=null)
function _getInitialWhere ($where)
function _processInstruction ($fieldarray)
function _qualify_dbname ($target_db, $this_db)
function _sqlAssembleWhere ($where, $where_array)
function _sqlAssembleWhereLink ($where, $where_array)
function _sqlForeignJoin (&$select, $from, $parent_relations)
function _sqlProcessJoin (&$select, $from, $reldata, &$new_relations)
function _sqlSelectAlternateLanguage ($sql_select, $reldata, $subquery=false)
function _switch_database ($tablename, $dbname)
function _validateInsert ($fieldarray)
function _validateUpdate ($fieldarray)
function __call ($method, $arguments)
function __sleep ()
function __wakeup ()
Just even looking at the “public” methods (without the underscore) there are 121 methods.
A few examples of the current problems, in my vision of a framework:
- commit, rollback - What if I want to commit/rollback a transaction involving more that one entity ? In which entity should I use this? A random one, all? And if all, what if one fails?
- post_fileUpload - Why should I care of this in the “database” layer? And if I don’t support file upload on a “Car” entity?
- getLanguageArray - I don’t care about multilanguage, and isn’t this a front-end responsibility?
- customButton - Again isn’t this front-end responsibility? Does it make sense use it in batch program? If not, what it is doing here?
Also, another quote from that article:
As far as I am concerned there is a one-to-one relationship between ‘entity’, ‘class’ and ‘database table’, so if ‘entity=class’ is correct and ‘entity=table’ is correct, how can ‘class=table’ be incorrect?
This is all plain wrong, any system/component can abstract another. So I can have an entity on my code (Person) that abstracts more that one table in the ER (Login + PersonDetails + AddressInfo + what ever I want) for many reasons: performance, obscure complexity, … I can have a many-to-many-to-many-to-many relationships. This is so true that if I had a one-to-one-to-one than I wouldn’t need an interface (different visions of my entities) just have a database system and let my users write it directly.