Revision 6
Added by Matt Wheeler about 14 years ago
Entity.php | ||
---|---|---|
1 | 1 |
<?php |
2 | 2 |
require_once('util/utilityFunctions.php'); |
3 | 3 |
require_once('objects/types.php'); |
4 |
require_once('objects/lookups.php'); |
|
4 | 5 |
|
5 | 6 |
class Entity { |
6 | 7 |
private $references = array(); |
... | ... | |
56 | 57 |
} |
57 | 58 |
|
58 | 59 |
switch($cNodeName) { |
59 |
#Untested |
|
60 | 60 |
case 'any': |
61 | 61 |
$any_e = $eList->newEntity($tableName . "_any_nodes"); |
62 | 62 |
$any_e->addMember("node_name","models.CharField(max_length=255)"); |
... | ... | |
92 | 92 |
} |
93 | 93 |
if($default != '') { |
94 | 94 |
if($use == 'optional' || |
95 |
$def == 'models.CharField(max_length=255') {
|
|
95 |
$def == 'models.CharField(max_length=255') { |
|
96 | 96 |
$def .= ", "; |
97 | 97 |
} |
98 | 98 |
$def .= "default = '$default'"; |
99 | 99 |
} |
100 |
if(needsIndex("attr_$a_name")) { |
|
101 |
if($use == 'optional' || |
|
102 |
$def == 'models.CharField(max_length=255' || |
|
103 |
$default != '') { |
|
104 |
$def .= ", "; |
|
105 |
} |
|
106 |
$def .= "db_index=True"; |
|
107 |
} |
|
100 | 108 |
$def .= ")"; |
101 | 109 |
if($guess) { $def .= " # This is a guess"; } |
102 | 110 |
$this->addMember("attr_$a_name",$def); |
... | ... | |
240 | 248 |
$def == 'models.CharField(max_length=255') { $def .= ", "; } |
241 | 249 |
$def .= "default = '$default'"; |
242 | 250 |
} |
251 |
if(needsIndex("attr_$a_name")) { |
|
252 |
if($use == 'optional' || |
|
253 |
$def == 'models.CharField(max_length=255' || |
|
254 |
$default != '') { |
|
255 |
$def .= ", "; |
|
256 |
} |
|
257 |
$def .= "db_index=True"; |
|
258 |
} |
|
243 | 259 |
$def .= ")"; |
244 | 260 |
if($guess) { $def .= " # This is a guess"; } |
245 | 261 |
$this->addMember("attr_$a_name",$def); |
... | ... | |
248 | 264 |
$this->addMember("primitive_type_value",$def); |
249 | 265 |
} else { |
250 | 266 |
$ref_e = $eList->getEntityForReference($base); |
251 |
$this->addOneToOneReference($base . "_extend",$ref_e); |
|
267 |
// $this->addOneToOneReference($base . "_extend",$ref_e); |
|
268 |
$this->addOneToManyReference($base . "_extend",$ref_e,False); |
|
252 | 269 |
$this->extensionType = $base; |
253 | 270 |
|
254 | 271 |
$grandchildNodesXPath = $xpath->query("child::node()",$childNode); |
... | ... | |
329 | 346 |
public function determineRelationship($colName,$typeName,$node) { |
330 | 347 |
global $eList; |
331 | 348 |
global $primitiveTypes; |
349 |
global $nativeVegXPointers; |
|
350 |
global $manyToManyRelationships; |
|
332 | 351 |
|
333 | 352 |
$tableName = $this->tableName; |
334 | 353 |
|
... | ... | |
338 | 357 |
$default = $node->getAttribute('default'); |
339 | 358 |
$default = $node->getAttribute('use'); |
340 | 359 |
|
341 |
if(isPrimitiveType($typeName)) { |
|
360 |
if(isNativePointer($colName)) { |
|
361 |
$def = $nativeVegXPointers[$colName]['def']; |
|
362 |
$this->addMember($colName,$def); |
|
363 |
} else if(isPrimitiveType($typeName)) { |
|
342 | 364 |
$def = $primitiveTypes[$typeName]; |
343 | 365 |
if($use == 'optional' || $optional) { |
344 | 366 |
if($def == 'models.CharField(max_length=255') { $def .= ", "; } |
... | ... | |
351 | 373 |
} |
352 | 374 |
$def .= "default = '$default'"; |
353 | 375 |
} |
376 |
if(needsIndex("$colName")) { |
|
377 |
if($use == 'optional' || $optional || |
|
378 |
$def == 'models.CharField(max_length=255' || |
|
379 |
$default != '') { |
|
380 |
$def .= ", "; |
|
381 |
} |
|
382 |
$def .= "db_index=True"; |
|
383 |
} |
|
354 | 384 |
$def .= ")"; |
355 | 385 |
|
356 | 386 |
if(((string)$maxOccurs) == '' || $maxOccurs == 1) { |
... | ... | |
365 | 395 |
} else { |
366 | 396 |
$ref_e = $eList->getEntityForReference($typeName); |
367 | 397 |
if(((string)$maxOccurs) == '' || $maxOccurs == 1) { |
368 |
$this->addOneToOneReference($colName,$ref_e,$optional); |
|
398 |
//$this->addOneToOneReference($colName,$ref_e,$optional); |
|
399 |
$this->addOneToManyReference($colName,$ref_e,False,$optional); |
|
369 | 400 |
} else { |
370 | 401 |
# echo "Need to define relationship between:\n $tableName <--> $typeName\n"; |
371 | 402 |
# echo " (O)ne to Many\n (M)any to Many\n"; |
372 | 403 |
# echo " Your choice: "; |
373 | 404 |
# $handle = fopen ("php://stdin","r"); |
374 | 405 |
# $line = fgets($handle); |
375 |
$line = 'M'; |
|
406 |
$line = 'O'; |
|
407 |
if($manyToManyRelationships[$tableName][$typeName]) { |
|
408 |
$line = 'M'; |
|
409 |
} |
|
376 | 410 |
if(trim($line) == 'O' || trim($line) == 'o'){ |
377 |
$ref_e->addOneToManyReference($colName,$this);
|
|
411 |
$ref_e->addOneToManyReference($tableName . "_id",$this,False,$optional);
|
|
378 | 412 |
$this->referrers[$colName] = $ref_e->getName(); |
379 | 413 |
} else { |
380 | 414 |
$this->addManyToManyReference($colName,$ref_e,$tableName . "_" . $typeName . "_" . $colName); |
... | ... | |
399 | 433 |
public function addOneToOneReference($colName,$e,$optional = False) { |
400 | 434 |
$eName = $e->getName(); |
401 | 435 |
$relatedName = $this->tableName . "_" . $colName; |
402 |
#$def = "models.OneToOneField('$eName', primary_key=True,related_name='$relatedName'"; |
|
403 | 436 |
$def = "models.ForeignKey('$eName', unique=True,related_name='$relatedName'"; |
404 | 437 |
if($optional) { |
405 | 438 |
$def .= ", null=True, blank=True"; |
... | ... | |
408 | 441 |
$this->addReference($colName,$def); |
409 | 442 |
} |
410 | 443 |
|
411 |
public function addOneToManyReference($colName,$e,$optional = False) { |
|
444 |
public function addOneToManyReference($colName,$e,$primitiveRef = True,$optional = False) {
|
|
412 | 445 |
$eName = $e->getName(); |
413 | 446 |
if($eName == $this->tableName) { |
414 | 447 |
$eName = 'self'; |
415 | 448 |
} |
416 | 449 |
$relatedName = $this->tableName . "_" . $colName; |
417 |
$def = "models.ForeignKey('$eName',related_name='$relatedName'"; |
|
450 |
#$def = "models.OneToOneField('$eName', primary_key=True,related_name='$relatedName'"; |
|
451 |
$def = "models.ForeignKey('$eName', related_name='$relatedName'"; |
|
418 | 452 |
if($optional) { |
419 | 453 |
$def .= ", null=True, blank=True"; |
420 | 454 |
} |
421 | 455 |
$def .= ")"; |
456 |
if(!$primitiveRef) { |
|
457 |
$def .= " #Complex one2Many"; |
|
458 |
} |
|
422 | 459 |
$this->addReference($colName,$def); |
423 | 460 |
} |
424 | 461 |
|
... | ... | |
494 | 531 |
|
495 | 532 |
public function toString() { |
496 | 533 |
$str = "class " . $this->tableName . "(models.Model):\n"; |
497 |
#Needed to keep Django from choking: |
|
498 |
if(count($this->references) == 0 && |
|
499 |
count($this->members) == 0) { |
|
500 |
$str .= " id = models.AutoField(primary_key=True)"; |
|
501 |
} |
|
502 | 534 |
|
535 |
#All entities need reference to their creation info since |
|
536 |
#VegX does not support unique identification for all types of information, |
|
537 |
#at least not as defined in BIEN3. |
|
538 |
$str .= " entryInfo = models.ForeignKey('EntryInfo')\n"; |
|
539 |
|
|
503 | 540 |
foreach(array_keys($this->references) as $colName) { |
504 | 541 |
$def = $this->references[$colName]; |
505 | 542 |
$str .= " $colName = $def\n"; |
... | ... | |
509 | 546 |
$str .= " $colName = $def\n"; |
510 | 547 |
} |
511 | 548 |
|
549 |
global $geoSpatialTypes; |
|
550 |
if($geoSpatialTypes[$this->tableName]) { |
|
551 |
//Only one geometry type per table currently so this works. |
|
552 |
$geoColDef = $geoSpatialTypes[$this->tableName]['colDef']; |
|
553 |
$str .= " \n # GeoDjango-specific: a geometry field, and\n". |
|
554 |
" # overriding the default manager with a GeoManager instance.\n". |
|
555 |
" $geoColDef\n". |
|
556 |
" objects = models.GeoManager()\n"; |
|
557 |
|
|
558 |
} |
|
559 |
|
|
512 | 560 |
$str .= "\n" . $this->makeExportFunction(); |
513 | 561 |
$str .= "\n" . $this->makeImportFunction(); |
514 | 562 |
$str .= "\n" . $this->makeExportDummyDataFunction(); |
563 |
$str .= "\n" . $this->makeRetrieveOrNewFunction(); |
|
515 | 564 |
|
516 | 565 |
#truncate table names that are too long for Django/Postgre to support |
517 | 566 |
if(strlen($this->tableName) > 54) { |
... | ... | |
528 | 577 |
if(count($this->references) == 0 && |
529 | 578 |
count($this->members) == 0 && |
530 | 579 |
count($this->referrers) == 0) { |
531 |
return " def importVegX(self,node):\n"." self.save()\n"; |
|
580 |
return " def importVegX(self,node,info):\n". |
|
581 |
" self.entryInfo = info\n". |
|
582 |
" self.save()\n"; |
|
532 | 583 |
} |
533 | 584 |
|
534 |
$def = " def importVegX(self,node):\n"; |
|
585 |
$def = " def importVegX(self,node,info):\n". |
|
586 |
" self.entryInfo = info\n"; |
|
535 | 587 |
|
536 | 588 |
if(preg_match_all("/([a-zA-Z]*)_extend/",implode(",",array_keys($this->references)),$matches) > 0) { |
537 | 589 |
$base = $matches[1][0]; |
538 |
$def .= " extendedEl = $base()\n". |
|
539 |
" extendedEl.importVegX(node)\n". |
|
590 |
$def .= " extendedEl = $base().retrieveOrNew(node)\n".
|
|
591 |
" extendedEl.importVegX(node,info)\n".
|
|
540 | 592 |
" self.$base"."_extend = extendedEl\n\n"; |
541 | 593 |
} |
542 | 594 |
|
... | ... | |
579 | 631 |
" newEl.$tIDName = self\n". |
580 | 632 |
" newEl.attr_name = attr\n". |
581 | 633 |
" newEl.attr_value = aVal\n". |
634 |
" newEl.entryInfo = info\n". |
|
582 | 635 |
" newEl.save()\n"; |
583 | 636 |
} else { |
584 | 637 |
$def .= " newEl = $type()\n". |
585 | 638 |
" newEl.$tIDName = self\n". |
586 | 639 |
" newEl.attr_name = attr\n". |
587 | 640 |
" newEl.attr_value = aVal\n". |
641 |
" newEl.entryInfo = info\n". |
|
588 | 642 |
" newEl.save()\n"; |
589 | 643 |
} |
590 | 644 |
} |
... | ... | |
604 | 658 |
preg_match_all("/primitive_type_value/",implode(",",array_keys($this->members)),$matches) > 0) { |
605 | 659 |
foreach(array_keys($this->members) as $colName) { |
606 | 660 |
if(preg_match("/^attr_/",$colName) > 0) { continue; } |
607 |
$ifStmt = $i == 0 ? 'if' : 'elif'; |
|
608 |
$i += 1; |
|
609 |
$def .= " $ifStmt cName == '$colName':\n". |
|
610 |
" cVal = child.childNodes[0].nodeValue\n". |
|
611 |
" self.$colName = cVal\n"; |
|
661 |
else if(isNativePointer($colName)) { |
|
662 |
global $nativeVegXPointers; |
|
663 |
$ifStmt = $i == 0 ? 'if' : 'elif'; |
|
664 |
$i += 1; |
|
665 |
$tabType = $nativeVegXPointers[$colName]['fk_type']; |
|
666 |
$toField = $nativeVegXPointers[$colName]['to_field']; |
|
667 |
$def .= " $ifStmt cName == '$colName':\n". |
|
668 |
" if(len(child.childNodes) > 0):\n". |
|
669 |
" cVal = child.childNodes[0].nodeValue\n". |
|
670 |
" q = $tabType.objects.filter($toField" . "__exact = cVal)\n". |
|
671 |
" q = $tabType.objects.filter(entryInfo__id__exact = self.entryInfo.id)\n". |
|
672 |
" if len(q) > 0:\n". |
|
673 |
" self.$colName = q[0]\n"; |
|
674 |
} else { |
|
675 |
$ifStmt = $i == 0 ? 'if' : 'elif'; |
|
676 |
$i += 1; |
|
677 |
$def .= " $ifStmt cName == '$colName':\n". |
|
678 |
" if(len(child.childNodes) > 0):\n". |
|
679 |
" cVal = child.childNodes[0].nodeValue\n". |
|
680 |
" self.$colName = cVal\n"; |
|
681 |
} |
|
612 | 682 |
} |
613 | 683 |
} |
614 | 684 |
|
615 | 685 |
if(preg_match_all("/primitive_type_value/",implode(",",array_keys($this->members)),$matches) > 0) { |
616 |
$def .= " cVal = node.childNodes[0].nodeValue\n". |
|
617 |
" self.primitive_type_value = cVal\n"; |
|
686 |
$def .= " if(len(node.childNodes) > 0):\n". |
|
687 |
" cVal = node.childNodes[0].nodeValue\n". |
|
688 |
" self.primitive_type_value = cVal\n"; |
|
618 | 689 |
} |
619 | 690 |
|
620 | 691 |
foreach(array_keys($this->references) as $colName) { |
... | ... | |
622 | 693 |
$colDef = $this->references[$colName]; |
623 | 694 |
|
624 | 695 |
if(preg_match("/(ForeignKey\(')([a-zA-Z]*)/",$colDef,$matches) > 0 && |
625 |
preg_match("/unique/",$colDef) > 0 && preg_match("/_extend/",$colName) == 0) {
|
|
696 |
preg_match("/Complex one2Many/",$colDef) > 0 && preg_match("/_extend/",$colDef) == 0) {
|
|
626 | 697 |
$i += 1; |
627 | 698 |
$def .= " $ifStmt cName == '$colName':\n". |
628 |
" newEl = $matches[2]()\n". |
|
629 |
" newEl.importVegX(child)\n". |
|
699 |
" newEl = $matches[2]().retrieveOrNew(child)\n".
|
|
700 |
" newEl.importVegX(child,info)\n".
|
|
630 | 701 |
" self.$colName = newEl\n"; |
631 | 702 |
} |
632 | 703 |
if(preg_match("/(ManyToManyField\(')([a-zA-Z]*)/",$colDef,$matches) > 0) { |
633 | 704 |
$i += 1; |
634 | 705 |
$def .= " $ifStmt cName == '$colName':\n". |
635 |
" newEl = $matches[2]()\n". |
|
636 |
" newEl.importVegX(child)\n". |
|
706 |
" newEl = $matches[2]().retrieveOrNew(child)\n".
|
|
707 |
" newEl.importVegX(child,info)\n".
|
|
637 | 708 |
" self.$colName.add(newEl)\n"; |
638 | 709 |
} |
639 | 710 |
} |
... | ... | |
649 | 720 |
$colDef = $this->referrers[$colName]; |
650 | 721 |
$elReferenceBack = $this->tableName . '_id'; |
651 | 722 |
$def .= " $ifStmt cName == '$colName':\n". |
652 |
" newEl = $colDef()\n". |
|
723 |
" newEl = $colDef().retrieveOrNew(child)\n".
|
|
653 | 724 |
" newEl.$elReferenceBack = self\n". |
654 |
" newEl.importVegX(child)\n"; |
|
725 |
" newEl.importVegX(child,info)\n";
|
|
655 | 726 |
} |
656 | 727 |
if(preg_match("/anyNode/",implode(",",array_keys($this->referrers))) > 0) { |
657 | 728 |
$type = $this->referrers['anyNode']; |
... | ... | |
663 | 734 |
" newEl.node_name = cName\n". |
664 | 735 |
" for grandchild in child.childNodes:\n". |
665 | 736 |
" newEl.node_value += grandchild.toxml()\n". |
737 |
" newEl.entryInfo = info\n". |
|
666 | 738 |
" newEl.save()\n"; |
667 | 739 |
} else { |
668 | 740 |
$def .= " newEl = $type()\n". |
... | ... | |
670 | 742 |
" newEl.node_name = cName\n". |
671 | 743 |
" for grandchild in child.childNodes:\n". |
672 | 744 |
" newEl.node_value += grandchild.toxml()\n". |
745 |
" newEl.entryInfo = info\n". |
|
673 | 746 |
" newEl.save()\n"; |
674 | 747 |
} |
675 | 748 |
} |
676 | 749 |
|
750 |
global $geoSpatialTypes; |
|
751 |
if($geoSpatialTypes[$this->tableName]) { |
|
752 |
//Only one geometry type per table currently so this works. |
|
753 |
$geoColImportDef = $geoSpatialTypes[$this->tableName]['importDef']; |
|
754 |
$def .= " \n # Convert to geometry types to make use of GeoDjango's\n". |
|
755 |
" # capabilities.\n". |
|
756 |
" $geoColImportDef\n"; |
|
757 |
|
|
758 |
} |
|
759 |
|
|
677 | 760 |
$def .= "\n self.save()\n"; |
678 | 761 |
return $def; |
679 | 762 |
|
... | ... | |
723 | 806 |
$def .= " if self.$colName != None:\n". |
724 | 807 |
" newElText = doc.createTextNode(self.$colName)\n". |
725 | 808 |
" myNode.appendChild(newElText)\n\n"; |
809 |
}else if(isNativePointer($colName)) { |
|
810 |
global $nativeVegXPointers; |
|
811 |
$to_field = $nativeVegXPointers[$colName]['to_field']; |
|
812 |
$nodeText = "str(self.$colName.$to_field)"; |
|
813 |
$def .= " if self.$colName != None:\n". |
|
814 |
" newEl = doc.createElement('$colName')\n". |
|
815 |
" newElText = doc.createTextNode($nodeText)\n". |
|
816 |
" newEl.appendChild(newElText)\n". |
|
817 |
" myNode.appendChild(newEl)\n\n"; |
|
726 | 818 |
}else { |
727 | 819 |
/* |
728 | 820 |
if(preg_match("/DateField/",$this->members[$colName],$matches) > 0 || |
... | ... | |
745 | 837 |
$colDef = $this->references[$colName]; |
746 | 838 |
|
747 | 839 |
if(preg_match("/(ForeignKey\(')([a-zA-Z]*)/",$colDef,$matches) > 0 && |
748 |
preg_match("/unique/",$colDef) > 0) {
|
|
840 |
(preg_match("/Complex one2Many/",$colDef) > 0 || preg_match("/_extend/",$colName) > 0)) {
|
|
749 | 841 |
if(preg_match("/_extend/",$colName) == 0) { |
750 | 842 |
$def .= " if self.$colName != None:\n". |
751 | 843 |
" newEl = doc.createElement('$colName')\n". |
... | ... | |
832 | 924 |
#Need to explicitly convert to string so minidom doesn't |
833 | 925 |
#roll over in nasty convulsions |
834 | 926 |
$randomFun = "str($randomFun())"; |
927 |
|
|
835 | 928 |
if(preg_match("/^attr_/",$colName,$matches) > 0) { |
836 | 929 |
$nodeName = preg_replace("/^attr_/","",$colName); |
837 | 930 |
$def .= " newAttr = doc.createAttribute('$nodeName')\n". |
... | ... | |
852 | 945 |
$colDef = $this->references[$colName]; |
853 | 946 |
|
854 | 947 |
if(preg_match("/(ForeignKey\(')([a-zA-Z]*)/",$colDef,$matches) > 0 && |
855 |
preg_match("/unique/",$colDef) > 0) {
|
|
948 |
(preg_match("/Complex one2Many/",$colDef) > 0 || preg_match("/_extend/",$colName) > 0)) {
|
|
856 | 949 |
if(preg_match("/_extend/",$colName) == 0) { |
857 | 950 |
$def .= " if '$matches[2]' not in usedObjectsStack:\n". |
858 | 951 |
" usedObjectsStack.append('$matches[2]')\n". |
... | ... | |
901 | 994 |
return $def; |
902 | 995 |
} |
903 | 996 |
|
997 |
public function makeRetrieveOrNewFunction() { |
|
998 |
global $idSysScope; |
|
999 |
global $idExtend; |
|
1000 |
global $adHoc; |
|
1001 |
global $adHocAttr; |
|
1002 |
|
|
1003 |
$tName = $this->tableName; |
|
1004 |
$def = " def retrieveOrNew(self,node):\n"; |
|
1005 |
|
|
1006 |
if($idExtend[$tName] != '' || $idSysScope[$tName] != ''){ |
|
1007 |
$extendedId = ''; |
|
1008 |
if($idExtend[$tName] != '') {$extendedId = $idExtend[$tName] . "__";} |
|
1009 |
$def .= " a_id = None\n". |
|
1010 |
" a_system = None\n". |
|
1011 |
" a_scope = None\n". |
|
1012 |
" for attr in node.attributes.keys():\n". |
|
1013 |
" aVal = node.attributes[attr].nodeValue\n". |
|
1014 |
" if attr == 'id':\n". |
|
1015 |
" a_id = aVal\n". |
|
1016 |
" elif attr == 'system':\n". |
|
1017 |
" a_system = aVal\n". |
|
1018 |
" elif attr == 'scope':\n". |
|
1019 |
" a_scope = aVal\n". |
|
1020 |
" if a_id != None:\n". |
|
1021 |
" q = $tName.objects.filter($extendedId" . "attr_id__exact = a_id)\n". |
|
1022 |
" if a_system != None:\n". |
|
1023 |
" q = q.filter($extendedId" . "attr_system__exact = a_system)\n". |
|
1024 |
" if a_scope != None:\n". |
|
1025 |
" q = q.filter($extendedId" . "attr_scope__exact = a_scope)\n". |
|
1026 |
" if len(q) > 0:\n". |
|
1027 |
" return q[0]\n". |
|
1028 |
" else:\n". |
|
1029 |
" return $tName()\n". |
|
1030 |
" else:\n". |
|
1031 |
" return $tName()\n"; |
|
1032 |
} else if($adHoc[$tName] != '') { |
|
1033 |
$def .= handleAdHoc($tName); |
|
1034 |
} else if($adHocAttr[$tName] != '') { |
|
1035 |
$def .= handleAdHocAttr($tName); |
|
1036 |
} else { |
|
1037 |
$def .= " return $tName()\n"; |
|
1038 |
} |
|
1039 |
return $def; |
|
1040 |
} |
|
1041 |
|
|
904 | 1042 |
public function makeSetupTestFunction() { |
905 | 1043 |
if(isPrimitiveType($this->tableName)) { return ""; } |
906 | 1044 |
|
Also available in: Unified diff
Adding vegx definition. Current models.py building script.