Project

General

Profile

1 3 wheeler
<?php
2
require_once('util/utilityFunctions.php');
3
require_once('objects/types.php');
4 6 wheeler
require_once('objects/lookups.php');
5 3 wheeler
6
class Entity {
7
  private $references = array();
8
  private $members = array();
9
  private $referrers = array();
10
  private $tableName;
11
  private $extensionType;
12
  private $inited;
13
14
  public function __construct($tableName,$node = null) {
15
    global $eList;
16
    // Entity name = table name
17
    $this->tableName = $tableName;
18
    $this->inited = False;
19
    $this->extensionType = '';
20
21
    if(!is_null($node)) {
22
      $this->init($tableName,$node);
23
      $this->inited = True;
24
    }
25
  }
26
27
  public function init($tableName,$node) {
28
    global $primitiveTypes;
29
    global $eList;
30
    $xpath = new DOMXPath($node->ownerDocument);
31
    $childNodesXPath = $xpath->query("child::node()",$node);
32
    $childNodes = array();
33
    foreach($childNodesXPath as $childNodeXPath) {
34
      $cNodeName = preg_replace("/.*:/","",$childNode->nodeName);
35
      if(!isIgnoreType($cNodeName)) {
36
        $childNodes[] = $childNodeXPath;
37
      }
38
    }
39
40
    for($i = 0; $i < count($childNodes); $i++) {
41
      $childNode = $childNodes[$i];
42
43
      $cNodeName = preg_replace("/.*:/","",$childNode->nodeName);
44
45
      if(isIgnoreType($cNodeName)) {
46
        continue;
47
      }
48
49
      #Very inefficient, but I want to be sure that I've handled all possible
50
      #attribute types.
51
      $attrs = $xpath->query("attribute::*",$childNode);
52
      foreach($attrs as $attr) {
53
        $attrName = $attr->name;
54
        if(!isKnownAttribute($attrName)) {
55
          throw new Exception("Encountered unkown attribute: $attrName in element $this->tableName.");
56
        }
57
      }
58
59
      switch($cNodeName) {
60
        case 'any':
61
          $any_e = $eList->newEntity($tableName . "_any_nodes");
62
          $any_e->addMember("node_name","models.CharField(max_length=255)");
63
          $any_e->addMember("node_value","models.TextField()");
64
          $any_e->addOneToManyReference($tableName . "_id",$this);
65
          $this->referrers['anyNode'] = $tableName . '_any_nodes';
66
          break;
67
        case 'anyAttribute':
68
          $any_a = $eList->newEntity($tableName . "_any_attr");
69
          $any_a->addMember("attr_name","models.CharField(max_length=255)");
70
          $any_a->addMember("attr_value","models.CharField(max_length=255)");
71
          $any_a->addOneToManyReference($tableName . "_id",$this);
72
          $this->referrers['anyAttribute'] = $tableName . '_any_attr';
73
          break;
74
        case 'attribute':
75
          $a_name = $childNode->getAttribute('name');
76
          if($a_name == '') {
77
            throw new Exception("Nodes defining attributes must have a name.  " .
78
                                "Unnamed attribute node found in $this->tableName.");
79
          }
80
          $default = $childNode->getAttribute('default');
81
          $use = $childNode->getAttribute('use');
82
          $type = preg_replace("/.*:/","",$childNode->getAttribute('type'));
83
          $guess = False;
84
          if($primitiveTypes[$type] != '') {
85
            $def = $primitiveTypes[$type];
86
          } else {
87
            $def = "models.CharField(max_length=255";
88
          }
89
          if($use == 'optional') {
90
            if($def == 'models.CharField(max_length=255') { $def .= ", "; }
91
            $def .= "null=True, blank=True";
92
          }
93
          if($default != '') {
94
            if($use == 'optional' ||
95 6 wheeler
               $def == 'models.CharField(max_length=255') {
96 3 wheeler
              $def .= ", ";
97
            }
98
            $def .= "default = '$default'";
99
          }
100 6 wheeler
          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
          }
108 3 wheeler
          $def .= ")";
109
          if($guess) { $def .= " # This is a guess"; }
110
          $this->addMember("attr_$a_name",$def);
111
          break;
112
        #Untested
113
        case 'group':
114
          if(hasImportantNodes($childNode)) {
115
            throw new Exception("No defined functionality for group nodes defining complex entities " .
116
                                "within other complex entities.");
117
          }
118
          $ref = preg_replace("/.*:/","",$childNode->getAttribute('ref'));
119
          if($ref == '') {
120
            throw new Exception("No defined functionality for group nodes " .
121
                                "that don't have a 'ref' attribute.");
122
          }
123
          $this->determineRelationship($ref,$ref,$childNode);
124
          break;
125
        case 'complexType':
126
          $name = $childNode->getAttribute('name');
127
          if($name != '') {
128
            throw new Exception("Named complexType definition within entity definition. " .
129
                                "This functionality is not yet implemented.");
130
          }
131
        case 'simpleType':
132
          $name = $childNode->getAttribute('name');
133
          if(isPrimitiveType($name)) {
134
            break;
135
          }
136
          if($name != '') {
137
            throw new Exception("Named simpleType definition within entity definition. " .
138
                                "This functionality is not yet implemented.");
139
          }
140
        case 'choice':
141
          # Fracking hack
142
          $isChoice = True;
143
        case 'complexContent':
144
        case 'simpleContent':
145
        case 'sequence':
146
          $minOccurs = $childNode->getAttribute('minOccurs');
147
          if($isChoice) {
148
            $minOccurs = 0;
149
          }
150
          $maxOccurs = $childNode->getAttribute('maxOccurs');
151
152
          #If defined, need to use pass these attribues through to child nodes.
153
          #Then, we add the grandchid nodes to the node list since we need the
154
          #grandchild nodes to complete the entity definition.
155
          $grandchildNodesXPath = $xpath->query("child::node()",$childNode);
156
          foreach($grandchildNodesXPath as $grandchildNodeXPath) {
157
            $gcNodeName = preg_replace("/.*:/","",$grandchildNodeXPath->nodeName);
158
            if(isIgnoreType($gcNodeName)) {
159
              continue;
160
            }
161
162
            if(((string)$minOccurs) != '') {
163
              $grandchildNodeXPath->setAttribute("minOccurs",$minOccurs);
164
            }
165
            if(((string)$maxOccurs) != '') {
166
              $grandchildNodeXPath->setAttribute("maxOccurs",$maxOccurs);
167
            }
168
            $childNodes[] = $grandchildNodeXPath;
169
          }
170
171
          #None of these have implemented functionality, need to fail if we reach
172
          #them during exection.
173
          $err_type = '';
174
          $default = $childNode->getAttribute('default');
175
          if($default != '' ) {
176
            $err_type = "default";
177
          }
178
          $use = $childNode->getAttribute('use');
179
          if($use != '' ) {
180
            $err_type = "use";
181
          }
182
          $mixed = $childNode->getAttribute('mixed');
183
          if($mixed != '' ) {
184
            $err_type = "mixed";
185
          }
186
          $type = $childNode->getAttribute('type');
187
          if($type != '' ) {
188
            $err_type = "type";
189
          }
190
          $namespace = $childNode->getAttribute('namespace');
191
          if($namespace != '' ) {
192
            $err_type = "namespace";
193
          }
194
          $nillable = $childNode->getAttribute('nillable');
195
          if($nillable != '' ) {
196
            $err_type = "nillable";
197
          }
198
          $ref = $childNode->getAttribute('ref');
199
          if($ref != '' ) {
200
            $err_type = "ref";
201
          }
202
          $base = $childNode->getAttribute('base');
203
          if($base != '' ) {
204
            $err_type = "base";
205
          }
206
          if($err_type != '') {
207
            throw new Exception("$err_type not defined for pass-through.");
208
          }
209
          break;
210
        case 'element':
211
          $this->handleElementCase($childNode);
212
          break;
213
        case 'extension':
214
          $name = findFirstAncestorName($childNode);
215
          $base = preg_replace("/.*:/","",$childNode->getAttribute('base'));
216
          if(isPrimitiveType($base)) {
217
            $grandchildNodesXPath = $xpath->query("child::node()",$childNode);
218
            foreach($grandchildNodesXPath as $grandchildNodeXPath) {
219
              $gcNodeName = preg_replace("/.*:/","",$grandchildNodeXPath->nodeName);
220
              if(isIgnoreType($gcNodeName)) {
221
                continue;
222
              }
223
              if($gcNodeName != 'attribute') {
224
                throw new Exception("Extension of primitive types can only add attributes, ".
225
                                    "found $gcNodeName.");
226
              }
227
              $a_name = $grandchildNodeXPath->getAttribute('name');
228
              if($a_name == '') {
229
                throw new Exception("Nodes defining attributes must have a name.  " .
230
                                    "Unnamed attribute node found in $this->tableName.");
231
              }
232
              $default = $grandchildNodeXPath->getAttribute('default');
233
              $use = $grandchildNodeXPath->getAttribute('use');
234
              $type = preg_replace("/.*:/","",$grandchildNodeXPath->getAttribute('type'));
235
              $guess = False;
236
              if($primitiveTypes[$type] != '') {
237
                $def = $primitiveTypes[$type];
238
              } else {
239
                $def = "models.CharField(max_length=255";
240
                $guess = True;
241
              }
242
              if($use == 'optional') {
243
                if($def == 'models.CharField(max_length=255') { $def .= ", "; }
244
                $def .= "null=True, blank=True";
245
              }
246
              if($default != '') {
247
                if($use == 'optional' ||
248
                   $def == 'models.CharField(max_length=255') { $def .= ", "; }
249
                $def .= "default = '$default'";
250
              }
251 6 wheeler
              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
              }
259 3 wheeler
              $def .= ")";
260
              if($guess) { $def .= " # This is a guess"; }
261
              $this->addMember("attr_$a_name",$def);
262
            }
263
            $def = $primitiveTypes[$base] . ")";
264
            $this->addMember("primitive_type_value",$def);
265
          } else {
266
            $ref_e = $eList->getEntityForReference($base);
267 6 wheeler
//            $this->addOneToOneReference($base . "_extend",$ref_e);
268
             $this->addOneToManyReference($base . "_extend",$ref_e,False);
269 3 wheeler
            $this->extensionType = $base;
270
271
            $grandchildNodesXPath = $xpath->query("child::node()",$childNode);
272
            foreach($grandchildNodesXPath as $grandchildNodeXPath) {
273
              $gcNodeName = preg_replace("/.*:/","",$grandchildNodeXPath->nodeName);
274
              if(isIgnoreType($gcNodeName)) {
275
                continue;
276
              }
277
              $childNodes[] = $grandchildNodeXPath;
278
            }
279
          }
280
          break;
281
        case 'restriction':
282
        case 'union':
283
        case 'maxInclusive':
284
        case 'minInclusive':
285
        case 'minExclusive':
286
        case 'list':
287
        case 'pattern':
288
        case 'fractionDigits':
289
          throw new Exception("No functionality defined for nodes of type: $cNodeName");
290
          break;
291
        default:
292
          throw new Exception("Encountered uknown nodes type: $cNodeName");
293
          break;
294
      }
295
    }
296
  }
297
298
  public function handleElementCase($childNode) {
299
    global $eList;
300
    global $primitiveTypes;
301
    $ref = preg_replace("/.*:/","",$childNode->getAttribute('ref'));
302
    $type = preg_replace("/.*:/","",$childNode->getAttribute('type'));
303
    if($ref != '') {
304
      $type = $ref;
305
    }
306
    $name = $childNode->getAttribute('name');
307 10 wheeler
    if($ref != '' && $name == '' /*&& !isPrimitiveType($ref)*/) {
308
      $name = $ref;
309 3 wheeler
    }
310
311
    if($name == '') {
312
      throw new Exception("All element nodes must have a name attribute, " .
313
                          "or a ref attribute to serve as the name.");
314
    }
315
316
    if($type != '') {
317
      $this->determineRelationship($name,$type,$childNode);
318
    } else {
319
      #Very hacky, but there a some cases where the element
320
      #has no type, and either 1) has some children nodes, but none of the
321
      #children nodes define a type, or 2) Has no useful nodes at all.
322
      # In this case the node is considered to be an anyType.
323
      $isDefined = False;
324
      $xpath = new DOMXPath($childNode->ownerDocument);
325
      $grandchildNodesXPath = $xpath->query("child::node()",$childNode);
326
      foreach($grandchildNodesXPath as $grandchildNodeXPath) {
327
        $gcNodeName = preg_replace("/.*:/","",$grandchildNodeXPath->nodeName);
328
        if(isIgnoreType($gcNodeName)) {
329
          continue;
330
        }
331
        if(hasImportantNodes($grandchildNodeXPath) || $grandchildNodeXPath->hasAttributes()) {
332
          $isDefined = True;
333
        }
334
      }
335
      if(!$isDefined) {
336
        $primitiveTypes[$name] = 'models.TextField(';
337
      }
338
339
      if(!isPrimitiveType($name)) {
340
        $eList->newEntity($name,$childNode);
341
      }
342
      $this->determineRelationship($name,$name,$childNode);
343
    }
344
  }
345
346
  public function determineRelationship($colName,$typeName,$node) {
347
    global $eList;
348
    global $primitiveTypes;
349 6 wheeler
    global $nativeVegXPointers;
350
    global $manyToManyRelationships;
351 3 wheeler
352
    $tableName = $this->tableName;
353
354
    $minOccurs = $node->getAttribute('minOccurs');
355
    $optional = $minOccurs == 0 ? True : False;
356
    $maxOccurs = $node->getAttribute('maxOccurs');
357
    $default = $node->getAttribute('default');
358
    $default = $node->getAttribute('use');
359
360 6 wheeler
    if(isNativePointer($colName)) {
361
      $def = $nativeVegXPointers[$colName]['def'];
362
      $this->addMember($colName,$def);
363
    } else if(isPrimitiveType($typeName)) {
364 3 wheeler
      $def = $primitiveTypes[$typeName];
365
      if($use == 'optional' || $optional) {
366
        if($def == 'models.CharField(max_length=255') { $def .= ", "; }
367
        $def .= "null=True, blank=True";
368
      }
369
      if($default != '') {
370
        if($use == 'optional' || $optional ||
371
           $def == 'models.CharField(max_length=255') {
372
          $def .= ", ";
373
        }
374
        $def .= "default = '$default'";
375
      }
376 6 wheeler
      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
      }
384 3 wheeler
      $def .= ")";
385
386
      if(((string)$maxOccurs) == '' || $maxOccurs == 1) {
387
        $this->addMember($colName,$def);
388
      } else {
389
        $refName = $this->tableName . "_" . $colName;
390
        $new_e = $eList->getEntityForReference($refName);
391
        $new_e->addMember("primitive_type_value",$def);
392
        $new_e->addOneToManyReference($tableName . "_id",$this);
393
        $this->referrers[$colName] = $refName;
394
      }
395
    } else {
396
      $ref_e = $eList->getEntityForReference($typeName);
397
      if(((string)$maxOccurs) == '' || $maxOccurs == 1) {
398 6 wheeler
        //$this->addOneToOneReference($colName,$ref_e,$optional);
399
        $this->addOneToManyReference($colName,$ref_e,False,$optional);
400 3 wheeler
      } else {
401
#        echo "Need to define relationship between:\n  $tableName <--> $typeName\n";
402
#        echo "    (O)ne to Many\n    (M)any to Many\n";
403
#        echo "    Your choice:  ";
404
#        $handle = fopen ("php://stdin","r");
405
#        $line = fgets($handle);
406 6 wheeler
        $line = 'O';
407
        if($manyToManyRelationships[$tableName][$typeName]) {
408
          $line = 'M';
409
        }
410 3 wheeler
        if(trim($line) == 'O' || trim($line) == 'o'){
411 6 wheeler
          $ref_e->addOneToManyReference($tableName . "_id",$this,False,$optional);
412 3 wheeler
          $this->referrers[$colName] = $ref_e->getName();
413
        } else {
414
          $this->addManyToManyReference($colName,$ref_e,$tableName . "_" . $typeName . "_" . $colName);
415
        }
416
      }
417
    }
418
  }
419
420
  private function addReference($colName,$definition) {
421
    # Probably shouldn't allow duplicate entries, most likely points to a problem.
422
    if(array_key_exists($colName,$this->references)) {
423
     $curDef = $this->references[$colName];
424
     throw new Exception("Attempting to overwrite/reinsert member $colName:$curDef with $colName:$definition in entity " . $this->tableName . ".");
425
    }
426
    $this->references[$colName] = $definition;
427
  }
428
429
  public function isInited() {
430
    return $this->inited;
431
  }
432
433
  public function addOneToOneReference($colName,$e,$optional = False) {
434
    $eName = $e->getName();
435
    $relatedName = $this->tableName . "_" . $colName;
436
    $def = "models.ForeignKey('$eName', unique=True,related_name='$relatedName'";
437
    if($optional) {
438
      $def .= ", null=True, blank=True";
439
    }
440
    $def .= ")";
441
    $this->addReference($colName,$def);
442
  }
443
444 6 wheeler
  public function addOneToManyReference($colName,$e,$primitiveRef = True,$optional = False) {
445 3 wheeler
    $eName = $e->getName();
446
    if($eName == $this->tableName) {
447
      $eName = 'self';
448
    }
449
    $relatedName = $this->tableName . "_" . $colName;
450 6 wheeler
    #$def = "models.OneToOneField('$eName', primary_key=True,related_name='$relatedName'";
451
    $def = "models.ForeignKey('$eName', related_name='$relatedName'";
452 3 wheeler
    if($optional) {
453
      $def .= ", null=True, blank=True";
454
    }
455
    $def .= ")";
456 6 wheeler
    if(!$primitiveRef) {
457
      $def .= " #Complex one2Many";
458
    }
459 3 wheeler
    $this->addReference($colName,$def);
460
  }
461
462
  public function addManyToManyReference($colName,$e,$db_table = '') {
463
    $eName = $e->getName();
464
    $relatedName = $this->tableName . "_" . $colName;
465
466
    $def = "models.ManyToManyField('$eName',related_name='$relatedName'";
467
468
    #Django chokes if the table/relation names are too long.  54 characters seems to
469
    #be a decent magic number.
470
    if($db_table != '' && strlen($db_table) > 54) {
471
      $db_table = 'v_' . substr($db_table,0,54);
472
      $def .= ",db_table = '$db_table'";
473
    }
474
    $def .= ")";
475
    $this->addReference($colName,$def);
476
  }
477
478
  public function addMember($colName, $definition) {
479
    # Probably shouldn't allow duplicate entries, most likely points to a problem.
480
    if(array_key_exists($colName,$this->members)) {
481
      $curDef = $this->members[$colName];
482
      if($curDef != $definition) {
483
        throw new Exception("Attempting to overwrite/reinsert member $colName:$curDef with $colName:$definition.");
484
      }
485
    }
486
    $this->members[$colName] = $definition;
487
  }
488
489
  public function getName() {
490
    return $this->tableName;
491
  }
492
493
  public function getReferences() {
494
    return $this->references;
495
  }
496
497
  public function getMembers() {
498
    return $this->members;
499
  }
500
501
  public function getReferrers() {
502
    return $this->referrers;
503
  }
504
505
  public function postProcess() {
506
    global $eList;
507
508
    #If we're dealing with extensions we need to pull the members, references, &
509
    #referrers of the base class.
510
    if($this->extensionType != '') {
511
      $base = $eList->getEntityForReference($this->extensionType);
512
      $baseReferences = $base->getReferences();
513
      $baseMembers = $base->getMembers();
514
      $baseReferrers = $base->getReferrers();
515
516
      $this->references = array_merge($this->references,$baseReferences);
517
      foreach(array_keys($this->references) as $k) {
518
        $def = $this->references[$k];
519
        $baseToken = $base->getName() . "_";
520
        $tableToken = $this->tableName . "_";
521
        $def = preg_replace("/$baseToken/","$tableToken",$def);
522
        $this->references[$k] = $def;
523
      }
524
525
      $this->members = array_merge($this->members,$baseMembers);
526
      $this->referrers = array_merge($this->referrers,$baseReferrers);
527
528
    }
529
530
  }
531
532
  public function toString() {
533 10 wheeler
    global $tableRenames;
534 3 wheeler
    $str = "class " . $this->tableName . "(models.Model):\n";
535
536 6 wheeler
    #All entities need reference to their creation info since
537
    #VegX does not support unique identification for all types of information,
538
    #at least not as defined in BIEN3.
539
    $str .= "  entryInfo = models.ForeignKey('EntryInfo')\n";
540
541 3 wheeler
    foreach(array_keys($this->references) as $colName) {
542
      $def = $this->references[$colName];
543 10 wheeler
      $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
544
      $str .= "  $effectiveColName = $def\n";
545 3 wheeler
    }
546
    foreach(array_keys($this->members) as $colName) {
547
      $def = $this->members[$colName];
548
      $str .= "  $colName = $def\n";
549
    }
550
551 6 wheeler
    global $geoSpatialTypes;
552
    if($geoSpatialTypes[$this->tableName]) {
553
      //Only one geometry type per table currently so this works.
554
      $geoColDef = $geoSpatialTypes[$this->tableName]['colDef'];
555
      $str .= "  \n  # GeoDjango-specific: a geometry field, and\n".
556
              "  # overriding the default manager with a GeoManager instance.\n".
557
              "  $geoColDef\n".
558
              "  objects = models.GeoManager()\n";
559
560
    }
561
562 3 wheeler
    $str .= "\n" . $this->makeExportFunction();
563
    $str .= "\n" . $this->makeImportFunction();
564
    $str .= "\n" . $this->makeExportDummyDataFunction();
565 6 wheeler
    $str .= "\n" . $this->makeRetrieveOrNewFunction();
566 3 wheeler
567
    #truncate table names that are too long for Django/Postgre to support
568
    if(strlen($this->tableName) > 54) {
569
      $tabName = 'v_' . substr($this->tableName,0,54);
570
      $str .= "\n\n  class Meta:\n".
571
              "    db_table = u'$tabName'\n\n";
572
    }
573
574 8 wheeler
    #there is a tablename resolution conflict between taxonNames/TaxonNames, taxonConcepts/TaxonConcepts,
575
    #temporalCoverage/TemporalCoverage in
576
    #that Django & Postgres store the table names in a case-insensitive way.  Need to force the table name
577
    #to be something different here.
578
    if($this->tableName == 'taxonNames') {
579
      $str .= "\n\n  class Meta:\n".
580
              "    db_table = u'v_taxonnames_lc'\n\n";
581
    } else if($this->tableName == 'TaxonNames') {
582
      $str .= "\n\n  class Meta:\n".
583
              "    db_table = u'v_taxonnames_uc'\n\n";
584
    } else if($this->tableName == 'taxonConcepts') {
585
      $str .= "\n\n  class Meta:\n".
586
              "    db_table = u'v_taxonconcepts_lc'\n\n";
587
    } else if($this->tableName == 'TaxonConcepts') {
588
      $str .= "\n\n  class Meta:\n".
589
              "    db_table = u'v_taxonconcepts_uc'\n\n";
590
    } else if($this->tableName == 'temporalCoverage') {
591
      $str .= "\n\n  class Meta:\n".
592
              "    db_table = u'v_temporalcoverage_lc'\n\n";
593
    } else if($this->tableName == 'TemporalCoverage') {
594
      $str .= "\n\n  class Meta:\n".
595
              "    db_table = u'v_temporalcoverage_uc'\n\n";
596
    }
597
598 3 wheeler
    return $str;
599
  }
600
601
  public function makeImportFunction() {
602 10 wheeler
    global $tableRenames;
603 3 wheeler
    #Slightly different if there are no members
604
    if(count($this->references) == 0 &&
605
       count($this->members) == 0 &&
606
       count($this->referrers) == 0) {
607 6 wheeler
      return "  def importVegX(self,node,info):\n".
608
             "    self.entryInfo = info\n".
609
             "    self.save()\n";
610 3 wheeler
    }
611
612 6 wheeler
    $def =  "  def importVegX(self,node,info):\n".
613
            "    self.entryInfo = info\n";
614 3 wheeler
615
    if(preg_match_all("/([a-zA-Z]*)_extend/",implode(",",array_keys($this->references)),$matches) > 0) {
616
      $base = $matches[1][0];
617 6 wheeler
      $def .= "    extendedEl = $base().retrieveOrNew(node)\n".
618
              "    extendedEl.importVegX(node,info)\n".
619 3 wheeler
              "    self.$base"."_extend = extendedEl\n\n";
620
    }
621
622
    $def .= "    self.save()\n";
623
624
    #Fun hack for anyAttribute & anyNode nodes
625
    if(preg_match("/_any_attr/",$this->tableName,$matches) > 0 ||
626
       preg_match("/_any_nodes/",$this->tableName,$matches) > 0) {
627
      return $def;
628
    }
629
630
    if(preg_match("/attr_/",implode(",",array_keys($this->members))) > 0 ||
631
       preg_match("/anyAttribute/",implode(",",array_keys($this->referrers))) > 0) {
632
      $def .= "    #attributes\n".
633
              "    for attr in node.attributes.keys():\n".
634
              "      aName = 'attr_' + attr\n".
635
              "      aVal = node.attributes[attr].nodeValue\n";
636
      $i = 0;
637
      foreach(array_keys($this->members) as $colName) {
638
        $ifStmt = $i == 0 ? 'if' : 'elif';
639
        if(preg_match("/^attr_/",$colName,$matches) > 0) {
640
          $i += 1;
641
          if(preg_match("/BooleanField/",$this->members[$colName],$matches) > 0) {
642
            $def .= "      $ifStmt aName == '$colName' and (aVal == 'true' or\n".
643
                    "      aVal == 'false' or aVal == 0 or aVal == 1):\n".
644
                    "        self.$colName = (aVal == 'true' or aVal == 1)\n";
645
          } else {
646
            $def .= "      $ifStmt aName == '$colName':\n".
647
                    "        self.$colName = aVal\n";
648
          }
649
        }
650
      }
651
    }
652
    if(preg_match("/anyAttribute/",implode(",",array_keys($this->referrers))) > 0) {
653
      $type = $this->referrers['anyAttribute'];
654
      $tIDName = $this->tableName . "_id";
655
      if(preg_match_all("/attr_/",implode(",",array_keys($this->members)),$matches) > 0) {
656
        $def .= "      else:\n".
657
                "        newEl = $type()\n".
658
                "        newEl.$tIDName = self\n".
659
                "        newEl.attr_name = attr\n".
660
                "        newEl.attr_value = aVal\n".
661 6 wheeler
                "        newEl.entryInfo = info\n".
662 3 wheeler
                "        newEl.save()\n";
663
      } else {
664
        $def .= "      newEl = $type()\n".
665
                "      newEl.$tIDName = self\n".
666
                "      newEl.attr_name = attr\n".
667
                "      newEl.attr_value = aVal\n".
668 6 wheeler
                "      newEl.entryInfo = info\n".
669 3 wheeler
                "      newEl.save()\n";
670
      }
671
    }
672
673
    if(count($this->members) -
674
       preg_match_all("/attr_/",implode(",",array_keys($this->members)),$matches) -
675
       preg_match_all("/primitive_type_value/",implode(",",array_keys($this->members)),$matches) > 0 ||
676
       count($this->references) > 0 || count($this->referrers) > 0) {
677
      $def .= "    #members & relationships\n".
678
              "    for child in node.childNodes:\n".
679
              "      cName = child.nodeName\n";
680
    }
681
682
    $i = 0;
683
    if(count($this->members) -
684
       preg_match_all("/attr_/",implode(",",array_keys($this->members)),$matches) -
685
       preg_match_all("/primitive_type_value/",implode(",",array_keys($this->members)),$matches) > 0) {
686
      foreach(array_keys($this->members) as $colName) {
687
        if(preg_match("/^attr_/",$colName) > 0) { continue; }
688 6 wheeler
        else if(isNativePointer($colName)) {
689
          global $nativeVegXPointers;
690
          $ifStmt = $i == 0 ? 'if' : 'elif';
691
          $i += 1;
692
          $tabType = $nativeVegXPointers[$colName]['fk_type'];
693
          $toField = $nativeVegXPointers[$colName]['to_field'];
694 10 wheeler
          $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
695
          $def .= "      $ifStmt cName == '$effectiveColName':\n".
696 6 wheeler
                  "        if(len(child.childNodes) > 0):\n".
697
                  "          cVal = child.childNodes[0].nodeValue\n".
698
                  "          q = $tabType.objects.filter($toField" . "__exact = cVal)\n".
699
                  "          q = $tabType.objects.filter(entryInfo__id__exact = self.entryInfo.id)\n".
700
                  "          if len(q) > 0:\n".
701 10 wheeler
                  "            self.$effectiveColName = q[0]\n";
702 6 wheeler
        } else {
703
          $ifStmt = $i == 0 ? 'if' : 'elif';
704
          $i += 1;
705 10 wheeler
          $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
706
          $def .= "      $ifStmt cName == '$effectiveColName':\n".
707 6 wheeler
                  "        if(len(child.childNodes) > 0):\n".
708
                  "          cVal = child.childNodes[0].nodeValue\n".
709 10 wheeler
                  "          self.$effectiveColName = cVal\n";
710 6 wheeler
        }
711 3 wheeler
      }
712
    }
713
714
    if(preg_match_all("/primitive_type_value/",implode(",",array_keys($this->members)),$matches) > 0) {
715 6 wheeler
      $def .= "    if(len(node.childNodes) > 0):\n".
716
              "      cVal = node.childNodes[0].nodeValue\n".
717
              "      self.primitive_type_value = cVal\n";
718 3 wheeler
    }
719
720
    foreach(array_keys($this->references) as $colName) {
721
      $ifStmt = $i == 0 ? 'if' : 'elif';
722
      $colDef = $this->references[$colName];
723
724
      if(preg_match("/(ForeignKey\(')([a-zA-Z]*)/",$colDef,$matches) > 0 &&
725 8 wheeler
         preg_match("/Complex one2Many/",$colDef) > 0 && preg_match("/_extend/",$colDef) == 0 &&
726
         preg_match("/_id/",$colName) == 0) {
727 3 wheeler
        $i += 1;
728 10 wheeler
        $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
729
        $def .= "      $ifStmt cName == '$effectiveColName':\n".
730 6 wheeler
                "        newEl = $matches[2]().retrieveOrNew(child)\n".
731
                "        newEl.importVegX(child,info)\n".
732 10 wheeler
                "        self.$effectiveColName = newEl\n";
733 3 wheeler
      }
734
      if(preg_match("/(ManyToManyField\(')([a-zA-Z]*)/",$colDef,$matches) > 0) {
735 10 wheeler
        $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
736 3 wheeler
        $i += 1;
737 10 wheeler
        $def .= "      $ifStmt cName == '$effectiveColName':\n".
738 6 wheeler
                "        newEl = $matches[2]().retrieveOrNew(child)\n".
739
                "        newEl.importVegX(child,info)\n".
740 10 wheeler
                "        self.$effectiveColName.add(newEl)\n";
741 3 wheeler
      }
742
    }
743
744
    if(count($this->referrers) > 0) {
745
      $def .= "      #These are the elements that refer to this one\n";
746
    }
747
    $allowAnyNode = False;
748
    foreach(array_keys($this->referrers) as $colName) {
749
      if($colName == 'anyAttribute' || $colName == 'anyNode') { continue; }
750
      $ifStmt = $i == 0 ? 'if' : 'elif';
751
      $i += 1;
752
      $colDef = $this->referrers[$colName];
753
      $elReferenceBack = $this->tableName . '_id';
754 10 wheeler
      $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
755
      $def .= "      $ifStmt cName == '$effectiveColName':\n".
756 6 wheeler
              "        newEl = $colDef().retrieveOrNew(child)\n".
757 3 wheeler
              "        newEl.$elReferenceBack = self\n".
758 6 wheeler
              "        newEl.importVegX(child,info)\n";
759 3 wheeler
    }
760
    if(preg_match("/anyNode/",implode(",",array_keys($this->referrers))) > 0) {
761
      $type = $this->referrers['anyNode'];
762
      $tIDName = $this->tableName . "_id";
763
      if($i > 0) {
764
        $def .= "      else:\n".
765
                "        newEl = $type()\n".
766
                "        newEl.$tIDName = self\n".
767
                "        newEl.node_name = cName\n".
768
                "        for grandchild in child.childNodes:\n".
769
                "          newEl.node_value += grandchild.toxml()\n".
770 6 wheeler
                "        newEl.entryInfo = info\n".
771 3 wheeler
                "        newEl.save()\n";
772
      } else {
773
        $def .= "      newEl = $type()\n".
774
                "      newEl.$tIDName = self\n".
775
                "      newEl.node_name = cName\n".
776
                "      for grandchild in child.childNodes:\n".
777
                "        newEl.node_value += grandchild.toxml()\n".
778 6 wheeler
                "      newEl.entryInfo = info\n".
779 3 wheeler
                "      newEl.save()\n";
780
      }
781
    }
782
783 6 wheeler
    global $geoSpatialTypes;
784
    if($geoSpatialTypes[$this->tableName]) {
785
      //Only one geometry type per table currently so this works.
786
      $geoColImportDef = $geoSpatialTypes[$this->tableName]['importDef'];
787
      $def .= "  \n    # Convert to geometry types to make use of GeoDjango's\n".
788
              "    # capabilities.\n".
789
              "  $geoColImportDef\n";
790
791
    }
792
793 3 wheeler
    $def .= "\n    self.save()\n";
794
    return $def;
795
796
  }
797
798
  public function makeExportFunction() {
799 10 wheeler
    global $tableRenames;
800
801 3 wheeler
    #Slightly different if there are no members
802
    if(count($this->references) == 0 &&
803
       count($this->members) == 0 &&
804
       count($this->referrers) == 0) {
805
      return "  def exportVegX(self,myNode,doc):\n".
806
             "    return myNode\n";
807
    }
808
809
    $def =  "  def exportVegX(self,myNode,doc):\n";
810
811
    #Fun hack for anyAttribute & anyNode nodes
812
    if(preg_match("/_any_attr/",$this->tableName,$matches) > 0) {
813
      $def .= "    newAttr = doc.createAttribute(self.attr_name)\n".
814
              "    newAttr.value = self.attr_value\n".
815
              "    return newAttr\n";
816
      return $def;
817
    }
818
    if(preg_match("/_any_nodes/",$this->tableName,$matches) > 0) {
819
      $def .= "    newEl = doc.createElement(self.node_name)\n".
820
              "    newElText = doc.createTextNode(self.node_value)\n".
821
              "    newEl.appendChild(newElText)\n".
822
              "    return newEl\n\n";
823
      return $def;
824
    }
825
826
    foreach(array_keys($this->members) as $colName) {
827
      $nodeName = $colName;
828
      $nodeText = "str(self.$colName)";
829
      //Python's string representation of booleans is True/False but xsd requires
830
      //true/false (lowercase) so we need this hack.
831
      if(preg_match("/NullBooleanField/",$this->members[$colName],$matches) > 0) {
832
        $nodeText = "string.lower(str(self.$colName))";
833
      }
834
      if(preg_match("/^attr_/",$colName,$matches) > 0) {
835
        $nodeName = preg_replace("/^attr_/","",$colName);
836
        $def .= "    if self.$colName != None:\n".
837
                "      newAttr = doc.createAttribute('$nodeName')\n".
838
                "      newAttr.value = $nodeText\n".
839
                "      myNode.setAttributeNode(newAttr)\n\n";
840
      } else if(preg_match("/primitive_type_value/",$colName,$matches) > 0) {
841
        $def .= "    if self.$colName != None:\n".
842
                "      newElText = doc.createTextNode(self.$colName)\n".
843
                "      myNode.appendChild(newElText)\n\n";
844 6 wheeler
      }else if(isNativePointer($colName)) {
845
        global $nativeVegXPointers;
846
        $to_field = $nativeVegXPointers[$colName]['to_field'];
847
        $nodeText = "str(self.$colName.$to_field)";
848
        $def .= "    if self.$colName != None:\n".
849
                "      newEl = doc.createElement('$colName')\n".
850
                "      newElText = doc.createTextNode($nodeText)\n".
851
                "      newEl.appendChild(newElText)\n".
852
                "      myNode.appendChild(newEl)\n\n";
853 3 wheeler
      }else {
854
/*
855
        if(preg_match("/DateField/",$this->members[$colName],$matches) > 0 ||
856
           preg_match("/TimeField/",$this->members[$colName],$matches) > 0 ||
857
           preg_match("/PositiveIntegerField/",$this->members[$colName],$matches) > 0 ||
858
           preg_match("/NullBooleanField/",$this->members[$colName],$matches) > 0 ||
859
           preg_match("/FloatField/",$this->members[$colName],$matches) > 0) {
860
          $nodeText = "str(self.$colName)";
861
        }
862
*/
863
        $def .= "    if self.$colName != None:\n".
864
                "      newEl = doc.createElement('$colName')\n".
865
                "      newElText = doc.createTextNode($nodeText)\n".
866
                "      newEl.appendChild(newElText)\n".
867
                "      myNode.appendChild(newEl)\n\n";
868
      }
869
    }
870
871
    foreach(array_keys($this->references) as $colName) {
872
      $colDef = $this->references[$colName];
873
874
      if(preg_match("/(ForeignKey\(')([a-zA-Z]*)/",$colDef,$matches) > 0 &&
875 8 wheeler
         (preg_match("/Complex one2Many/",$colDef) > 0 || preg_match("/_extend/",$colName) > 0) &&
876
         preg_match("/_id/",$colName) == 0) {
877 10 wheeler
        $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
878 3 wheeler
        if(preg_match("/_extend/",$colName) == 0) {
879 10 wheeler
          $def .= "    if self.$effectiveColName != None:\n".
880
                  "      newEl = doc.createElement('$effectiveColName')\n".
881
                  "      myNode.appendChild(self.$effectiveColName.exportVegX(newEl,doc))\n\n";
882 3 wheeler
        } else {
883
          $def .= "    if self.$colName != None:\n".
884
                  "      myNode = self.$colName.exportVegX(myNode,doc)\n\n";
885
        }
886
      }
887
      if(preg_match("/(ManyToManyField\(')([a-zA-Z]*)/",$colDef,$matches) > 0) {
888 10 wheeler
        $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
889 3 wheeler
        $def .= "    for childRef in self.$colName.all():\n".
890 10 wheeler
                "      newEl = doc.createElement('$effectiveColName')\n".
891 3 wheeler
                "      myNode.appendChild(childRef.exportVegX(newEl,doc))\n\n";
892
      }
893
    }
894
895
    foreach(array_keys($this->referrers) as $nodeName) {
896 8 wheeler
      $nodeNameToUse = $this->referrers[$nodeName];
897 3 wheeler
      if($nodeName == 'anyAttribute') {
898 8 wheeler
        $nodeNameToUse = $this->tableName . '_any_attr';
899
        $relatedName = $nodeNameToUse . '_' . $this->tableName . '_id';
900 3 wheeler
        $def .= "    for childRef in self.$relatedName.all():\n".
901
                "      newEl = doc.createAttribute('$nodeName')\n".
902
                "      myNode.setAttributeNode(childRef.exportVegX(newEl,doc))\n\n";
903
      } else {
904
        if($nodeName == 'anyNode') {
905 8 wheeler
          $nodeNameToUse = $this->tableName . '_any_nodes';
906 3 wheeler
        }
907 8 wheeler
        $relatedName = $nodeNameToUse . '_' . $this->tableName . '_id';
908 10 wheeler
        $effectiveNodeName = $nodeName;
909
        if($tableRenames[$nodeName] != null) {
910
          $effectiveNodeName = $tableRenames[$nodeName];
911
        }
912 3 wheeler
        $def .= "    for childRef in self.$relatedName.all():\n".
913 10 wheeler
                "      newEl = doc.createElement('$effectiveNodeName')\n".
914 3 wheeler
                "      myNode.appendChild(childRef.exportVegX(newEl,doc))\n\n";
915
      }
916
    }
917
918
    $def .= "    return myNode\n";
919
    return $def;
920
  }
921
922
  public function makeExportDummyDataFunction() {
923 10 wheeler
    global $tableRenames;
924 3 wheeler
    #Slightly different if there are no members
925
    if(count($this->references) == 0 &&
926
       count($this->members) == 0 &&
927
       count($this->referrers) == 0) {
928
      return "  def exportDummyVegX(self,myNode,doc,usedObjectsStack):\n".
929
             "    return myNode\n";
930
    }
931
932
    $def =  "  def exportDummyVegX(self,myNode,doc,usedObjectsStack):\n";
933
934
    #Fun hack for anyAttribute & anyNode nodes
935
    if(preg_match("/_any_attr/",$this->tableName,$matches) > 0) {
936
      $def .= "    newAttr = doc.createAttribute(getRandomString())\n".
937
              "    newAttr.value = getRandomString()\n".
938
              "    return newAttr\n";
939
      return $def;
940
    }
941
    if(preg_match("/_any_nodes/",$this->tableName,$matches) > 0) {
942
      $def .= "    newEl = doc.createElement(getRandomString())\n".
943
              "    newElText = doc.createTextNode(getRandomText())\n".
944
              "    newEl.appendChild(newElText)\n".
945
              "    return newEl\n\n";
946
      return $def;
947
    }
948
949
    foreach(array_keys($this->members) as $colName) {
950
      $nodeName = $colName;
951
      $colDef = $this->members[$colName];
952
      $randomFun = "getRandomString";
953
      if(preg_match("/FloatField/",$colDef,$matches) > 0) {
954
        $randomFun = "getRandomFloat";
955
      } else if(preg_match("/IntegerField/",$colDef,$matches) > 0) {
956
        $randomFun = "getRandomInt";
957
      } else if(preg_match("/TextField/",$colDef,$matches) > 0) {
958
        $randomFun = "getRandomText";
959
      } else if(preg_match("/DateField/",$colDef,$matches) > 0) {
960
        $randomFun = "getRandomDate";
961
      } else if(preg_match("/TimeField/",$colDef,$matches) > 0) {
962
        $randomFun = "getRandomTime";
963
      } else if(preg_match("/NullBooleanField/",$colDef,$matches) > 0) {
964
        $randomFun = "getRandomBool";
965
      }
966
967
      #Need to explicitly convert to string so minidom doesn't
968
      #roll over in nasty convulsions
969
      $randomFun = "str($randomFun())";
970 6 wheeler
971 3 wheeler
      if(preg_match("/^attr_/",$colName,$matches) > 0) {
972
        $nodeName = preg_replace("/^attr_/","",$colName);
973
        $def .= "    newAttr = doc.createAttribute('$nodeName')\n".
974
                "    newAttr.value = $randomFun\n".
975
                "    myNode.setAttributeNode(newAttr)\n\n";
976
      } else if(preg_match("/primitive_type_value/",$colName,$matches) > 0) {
977
        $def .= "    newElText = doc.createTextNode($randomFun)\n".
978
                "    myNode.appendChild(newElText)\n\n";
979
      }else {
980
        $def .= "    newEl = doc.createElement('$colName')\n".
981
                "    newElText = doc.createTextNode($randomFun)\n".
982
                "    newEl.appendChild(newElText)\n".
983
                "    myNode.appendChild(newEl)\n\n";
984
      }
985
    }
986
987
    foreach(array_keys($this->references) as $colName) {
988
      $colDef = $this->references[$colName];
989
990
      if(preg_match("/(ForeignKey\(')([a-zA-Z]*)/",$colDef,$matches) > 0 &&
991 8 wheeler
         (preg_match("/Complex one2Many/",$colDef) > 0 || preg_match("/_extend/",$colName) > 0) &&
992
         preg_match("/_id/",$colName) == 0) {
993 3 wheeler
        if(preg_match("/_extend/",$colName) == 0) {
994 10 wheeler
          $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
995 3 wheeler
          $def .= "    if '$matches[2]' not in usedObjectsStack:\n".
996
                  "      usedObjectsStack.append('$matches[2]')\n".
997 10 wheeler
                  "      newEl = doc.createElement('$effectiveColName')\n".
998 3 wheeler
                  "      newElObj = $matches[2]()\n".
999
                  "      myNode.appendChild(newElObj.exportDummyVegX(newEl,doc,usedObjectsStack))\n".
1000
                  "      usedObjectsStack.pop()\n\n";
1001
        } else {
1002
          $def .= "    if '$matches[2]' not in usedObjectsStack:\n".
1003
                  "      usedObjectsStack.append('$matches[2]')\n".
1004
                  "      newElObj = $matches[2]()\n".
1005
                  "      myNode = newElObj.exportDummyVegX(myNode,doc,usedObjectsStack)\n".
1006
                  "      usedObjectsStack.pop()\n\n";
1007
        }
1008
      }
1009
      if(preg_match("/(ManyToManyField\(')([a-zA-Z]*)/",$colDef,$matches) > 0) {
1010 10 wheeler
        $effectiveColName = $tableRenames[$colName] == null ? $colName : $tableRenames[$colName];
1011 3 wheeler
        $def .= "    if '$matches[2]' not in usedObjectsStack:\n".
1012
                "      usedObjectsStack.append('$matches[2]')\n".
1013 10 wheeler
                "      newEl = doc.createElement('$effectiveColName')\n".
1014 3 wheeler
                "      newElObj = $matches[2]()\n".
1015
                "      myNode.appendChild(newElObj.exportDummyVegX(newEl,doc,usedObjectsStack))\n".
1016
                "      usedObjectsStack.pop()\n\n";
1017
      }
1018
    }
1019
1020
    foreach(array_keys($this->referrers) as $nodeName) {
1021
      $colDef = $this->referrers[$nodeName];
1022
      if($nodeName == 'anyAttribute') {
1023
        $def .= "    if '$colDef' not in usedObjectsStack:\n".
1024
                "      usedObjectsStack.append('$colDef')\n".
1025
                "      newEl = doc.createAttribute(getRandomText())\n".
1026
                "      childRef = $colDef()\n".
1027
                "      myNode.setAttributeNode(childRef.exportDummyVegX(newEl,doc,usedObjectsStack))\n".
1028
                "      usedObjectsStack.pop()\n\n";
1029
      } else {
1030 10 wheeler
        $effectiveNodeName = $tableRenames[$nodeName] == null ? $nodeName : $tableRenames[$nodeName];
1031 3 wheeler
        $def .= "    if '$colDef' not in usedObjectsStack:\n".
1032
                "      usedObjectsStack.append('$colDef')\n\n".
1033 10 wheeler
                "      newEl = doc.createElement('$effectiveNodeName')\n".
1034 3 wheeler
                "      childRef = $colDef()\n".
1035
                "      myNode.appendChild(childRef.exportDummyVegX(newEl,doc,usedObjectsStack))\n".
1036
                "      usedObjectsStack.pop()\n\n";
1037
      }
1038
    }
1039
1040
    $def .= "    return myNode\n";
1041
    return $def;
1042
  }
1043
1044 6 wheeler
  public function makeRetrieveOrNewFunction() {
1045
    global $idSysScope;
1046
    global $idExtend;
1047
    global $adHoc;
1048
    global $adHocAttr;
1049
1050
    $tName = $this->tableName;
1051
    $def = "  def retrieveOrNew(self,node):\n";
1052
1053
    if($idExtend[$tName] != '' || $idSysScope[$tName] != ''){
1054
      $extendedId = '';
1055
      if($idExtend[$tName] != '') {$extendedId = $idExtend[$tName] . "__";}
1056
      $def .= "    a_id = None\n".
1057
              "    a_system = None\n".
1058
              "    a_scope = None\n".
1059
              "    for attr in node.attributes.keys():\n".
1060
              "      aVal = node.attributes[attr].nodeValue\n".
1061
              "      if attr == 'id':\n".
1062
              "        a_id = aVal\n".
1063
              "      elif attr == 'system':\n".
1064
              "        a_system = aVal\n".
1065
              "      elif attr == 'scope':\n".
1066
              "        a_scope = aVal\n".
1067
              "    if a_id != None:\n".
1068
              "      q = $tName.objects.filter($extendedId" . "attr_id__exact = a_id)\n".
1069
              "      if a_system != None:\n".
1070
              "        q = q.filter($extendedId" . "attr_system__exact = a_system)\n".
1071
              "      if a_scope != None:\n".
1072
              "        q = q.filter($extendedId" . "attr_scope__exact = a_scope)\n".
1073
              "      if len(q) > 0:\n".
1074
              "        return q[0]\n".
1075
              "      else:\n".
1076
              "        return $tName()\n".
1077
              "    else:\n".
1078
              "      return $tName()\n";
1079
    } else if($adHoc[$tName] != '') {
1080
      $def .= handleAdHoc($tName);
1081
    } else if($adHocAttr[$tName] != '') {
1082
      $def .= handleAdHocAttr($tName);
1083
    } else {
1084
      $def .= "    return $tName()\n";
1085
    }
1086
    return $def;
1087
  }
1088
1089 3 wheeler
  public function makeSetupTestFunction() {
1090
    if(isPrimitiveType($this->tableName)) { return ""; }
1091
1092
    $def = "  def setUp(self):\n".
1093
           "    self.impl = getDOMImplementation()\n".
1094
           "    self.newdoc = self.impl.createDocument(None, " . $this->tableName . ", None)\n".
1095
           "    top_element = newdoc.documentElement\n";
1096
  }
1097
1098
  public function makeImportTestFunction() {
1099
  }
1100
1101
  public function makeExportTestFunction() {
1102
  }
1103
1104
}
1105
?>