/** * Obtiene solo una asociacion. */ public function get_many_assoc_lazy(PersistentObject $obj, $hmattr) { Logger::getInstance()->pm_log("PM.get_many_assoc_lazy " . get_class($obj) . " " . $hmattr); // TODO: tengo que cargar solo si tiene deleted en false en la tabla de join. // FIXME: esta clase podria ser superclase de la subclase que quiero cargar. // tengo que ver en la tabla de que tipo es realmente y cargar una instancia de eso. $hmattrClazz = $obj->getAttributeType($hmattr); // (***) $relObjIns = new $hmattrClazz(); // Intancia para hallar nombre de tabla. $relObjTableName = YuppConventions::tableName($relObjIns); $relTableName = ""; $obj_is_owner = $obj->isOwnerOf($hmattr); if ($obj_is_owner) { $relTableName = YuppConventions::relTableName($obj, $hmattr, $relObjIns); } else { // Si no soy owner tengo que pedir el atributo... $ownerInstance = $relObjIns; // FIXME: si ownerInstance tiene 2 relaciones HM con la class del $obj, este metodo retorna NULL. $ownerAttrNameOfSameAssoc = $ownerInstance->getHasManyAttributeNameByAssocAttribute(get_class($obj), $hmattr); //echo "Call to relTableName hmattr=$hmattr ownerAttr=$ownerAttrNameOfSameAssoc ".__FILE__.__LINE__."<br/>"; $relTableName = YuppConventions::relTableName($ownerInstance, $ownerAttrNameOfSameAssoc, $obj); } // ================================================================================= // (***) // FIXME: deberia hacer un join con la tabla de referencia y la // tabla destino para traer todos los atributos y no tener // que hacer consultas individuales para cargar cada objeto. // // ================================================================================= // ================================================================================= // QIERO PEDIR SOLO LOS ELEMENTOS DE ObjectReference, para poder recorrerlo y ver si ya tengo objetos cargados, // y cargo solo los que no estan cargados. Seteo todos los objetos al atributo hasMany del objeto. YuppLoader::load('core.db.criteria2', 'Query'); $q = new Query(); $q->addFrom($relTableName, 'ref'); // person_phone ref // FIXME: ESTO ES addFrom. $q->addFrom($relObjTableName, 'obj'); // FIXME: quiero todos los atributos... // Se agregan los atributos de la clase como proyeccion de la query. // Solo quiero los atributos de OBJ, agrego sus atributos como proyecciones de la consulta. /* esto seleccionaba solo los atributos declarados en la clase. foreach( $_obj->getAttributeTypes() as $attr => $type ) { //$q->addProjection("obj", $attr); // TODO: normalizar en la query mismo $q->addProjection( "obj", DatabaseNormalization::col($attr) ); } */ $q->addProjection('obj', '*'); // Todos los atributos de la tabla con alias "obj". // Necesito saber el nombre del atributo de los ids asociados. $hm_assoc_attr = "owner_id"; // FIXME: poner el string en una clase de convensiones de yupp // Los ids de todas las instnacias parciales de la clase declarada en el atributo // hasMany, van a ser todos iguales, por eso uso el id del objeto que viene. $obj_id = $obj->getId(); // Tengo que ver el objeto en la tabla de referehcia si es el owner_id o el ref_id if ($obj_is_owner) { // FIXME: poner el string en una clase de convensiones de yupp $hm_assoc_attr = 'ref_id'; // yo soy el owner entonces el asociado es ref. $q->setCondition(Condition::_AND()->add(Condition::EQ('ref', 'owner_id', $obj_id))->add(Condition::EQA('obj', 'id', 'ref', 'ref_id'))); } else { $q->setCondition(Condition::_AND()->add(Condition::EQ('ref', 'ref_id', $obj_id))->add(Condition::EQ('ref', 'type', ObjectReference::TYPE_BIDIR))->add(Condition::EQA('obj', 'id', 'ref', 'owner_id'))); } // ========================================================================== // Desde v0.1.6: soporte para tipos de hasMany // Si es de tipo lista, debe donsiderar el orden. if ($obj->getHasManyType($hmattr) === PersistentObject::HASMANY_LIST) { $q->addOrder("ref", "ord", "ASC"); // Orden ascendente por atributo ORD de la tabla intermedia. } Logger::getInstance()->pm_log("PersistentManager.get_many_assoc_lazy query " . __FILE__ . " " . __LINE__); // Trae todos los objetos linkeados... (solo sus atributos simples) $data = $this->dal->query($q); // FIN QUERY... $wasDirty = $obj->isDirtyMany(); // Ojo, se prenden bits de dirty (es necesario detectar si no estaba dirty antes, para saber si puede limpiar). $obj->aSet($hmattr, array()); // Inicalizo lista xq seguramente estaba en NOT_LOADED. foreach ($data as $many_attrValues) { /* Esta cargado? * $rel_obj_id = $many_attrValues[ $hm_assoc_attr ]; // El codigo que usa esta linea esta comentado... * if ( ArtifactHolder::getInstance()->existsModel( $hmattrClazz, $rel_obj_id ) ) * { * $rel_obj = ArtifactHolder::getInstance()->getModel( $hmattrClazz, $rel_obj_id ); * } * else * { * $rel_obj = $this->get_object( $hmattrClazz, $rel_obj_id ); // Carga solo el objeto, sin asociaciones. * ArtifactHolder::getInstance()->addModel( $rel_obj ); // FIXME: ArtHolder deberia referenciarse solo del PM!!!!! * } */ // Esto soluciona la carga de autorrelacion desde una subclase. // B(heredaDe)A y A(hasMany)A, y quiero cargar B que a su vez tiene asociados varios Bs. // FIXME: esta clase podria ser superclase de la subclase que quiero cargar. // tengo que ver en la tabla de que tipo es realmente y cargar una instancia de eso. // (***) //$rel_obj = $this->createObjectFromData( $hmattrClazz, $many_attrValues ); if ($many_attrValues['class'] === $hmattrClazz) { // FIXME: si el rel_obj tiene hasOne, y hereda de otra clase, no se cargan los hasOne. //Logger::getInstance()->pm_log("Caso1: $hmattrClazz ". __FILE__ ." ". __LINE__); //Logger::struct($many_attrValues, "many_attrValues"); //echo " la clase es la misma que la declarada<br/>"; $rel_obj = $this->createObjectFromData($hmattrClazz, $many_attrValues); } else { //Logger::getInstance()->pm_log("Caso2: [$hmattrClazz / ". $many_attrValues['class'] ."] " . __FILE__ ." ". __LINE__); //Logger::struct($many_attrValues, "many_attrValues"); //echo " la clase NO es la misma que la declarada<br/>"; // TODO: deberia cargar los atributos declarados en la clase $many_attrValues['class'], que estan en otra tabla que la que acabo de cargar. // por ejemplo el id cargado es el de una superclase no el de la clase que deberia ser la instancia. $rel_obj = $this->get_mti_object_byData($hmattrClazz, $many_attrValues); } $obj->aAddTo($hmattr, $rel_obj); } if (!$wasDirty) { $obj->resetDirtyMany(); } }