3 require_once("ORMObjectSetGenerator.php");
5 class ORMSQLSetGenerator
extends ORMObjectSetGenerator
{
6 public $relations; /** a relation is a way to declare a many-to-one for sql */
9 protected $visitor_class = "LivestatusSQLBuilderVisitor";
11 public function __construct( $name, $structure ) {
12 parent
::__construct($name, $structure);
14 $this->relations
= array();
16 if (isset($this->structure
['relations'])) {
17 foreach ($this->structure
['relations'] as $relation) {
18 list($foreign_key, $table, $key) = $relation;
19 $this->relations
[$this->structure
['structure'][$key][1]] = array(
20 'tbl' => $structure[$table]['table'],
21 'tblkey' => $structure[$table]['key'],
25 $this->structure
['relations'] = array();
28 $this->db_instance
= false;
29 if( isset($this->structure
['db_instance']) ) {
30 $this->db_instance
= $this->structure
['db_instance'];
34 public function generate_backend_specific_functions() {
37 public function generate_stats() {
38 $this->init_function('stats',array('intersections'));
39 $this->write('return array();');
40 $this->finish_function();
43 private function build_sql_from_where() {
45 $this->write('$sql .= %s;', ' FROM ' . $this->structure
['table'] . ' AS ' . $this->name
);
46 foreach ($this->structure
['relations'] as $relation) {
47 list($foreign_key, $foreign_table, $key) = $relation;
48 $foreign_structure = $this->full_structure
[$foreign_table];
49 $ftable = $foreign_structure['table'];
50 $join_expr = ' LEFT JOIN '.$ftable.' AS '.$key;
51 $join_expr .= ' ON '.implode(' AND ',array_map(function($fk,$lk) use($key,$table) {
52 return "$key.$fk = $table.$lk";
53 }, $foreign_structure['key'], $foreign_key));
54 $this->write('$sql .= %s;', $join_expr);
56 $this->write('$filter = $this->get_auth_filter();');
57 $this->write('$sql .= " WHERE ".$filter->visit(new '.$this->visitor_class
.'(array(%s, "map_name_to_backend")), false);', $this->structure
['class'].'Set'.self
::$model_suffix);
60 public function generate_count() {
61 $this->init_function('count');
62 $this->write('$db = Database::instance(%s);',$this->db_instance
);
63 $this->write('$filter = $this->get_auth_filter();');
64 $this->write('$sql = "SELECT COUNT(*) AS count";');
65 $this->build_sql_from_where();
66 $this->write('$q = $db->query($sql);');
67 $this->write('$q->result(false);');
68 $this->write('$row = $q->current();');
69 $this->write('return $row["count"];');
70 $this->finish_function();
73 public function generate_it() {
75 $this->init_function( 'it', array('columns','order','limit','offset'), array(), array('order' => array(), 'limit'=>false, 'offset'=>false) );
76 $this->write('$db = Database::instance(%s);',$this->db_instance
);
78 $this->write('$valid_columns = false;');
79 $this->write('if( $columns !== false ) {');
80 $this->write( '$processed_columns = array_merge($columns, $this->key_columns);');
81 $this->write( '$processed_columns = static::apply_columns_rewrite($processed_columns);');
82 $this->write( '$valid_columns = array();');
83 $this->write( 'foreach($processed_columns as $col) {');
84 $this->write( '$new_name = static::map_name_to_backend($col);');
85 $this->write( 'if($new_name !== false) {');
86 $this->write( '$valid_columns[] = $new_name;');
89 $this->write( '$valid_columns = array_unique($valid_columns);');
92 $this->write('$sql = "SELECT ";');
93 $this->write('if ($valid_columns === false) {');
94 $table_names = array($this->name
);
95 foreach( $this->structure
['relations'] as $rel ) {
96 $table_names[] = $rel[2];
98 $this->write( '$sql .= %s;', implode(', ', array_map(function($rel) { return $rel . '.*'; }, $table_names)));
99 $this->write('} else {');
100 $this->write( '$sql .= implode(", ", $valid_columns);');
102 $this->build_sql_from_where();
104 $this->write('$sort = array();');
105 foreach(array('$order','$this->default_sort') as $sortfield) {
106 $this->write('foreach('.$sortfield.' as $col_attr) {');
107 $this->write( '$parts = explode(" ",$col_attr,2);');
108 $this->write( 'if(isset($parts[1]) && !preg_match("/^(asc|desc)$/i",$parts[1])) continue;');
109 $this->write( '$original_part_0 = $parts[0];');
110 $this->write( '$parts[0] = static::map_name_to_backend($parts[0]);');
111 $this->write( 'if($parts[0] === false) {');
112 $this->write( 'throw new ORMException(%s.$original_part_0."\'");', "Table '".$this->name
."' has no column '");
114 $this->write( '$sort[] = implode(" ",$parts);');
117 $this->write('if(!empty($sort)) {');
118 $this->write('$sql .= " ORDER BY ".implode(", ",$sort);');
121 $this->write('if( $limit !== false ) {');
122 $this->write( '$sql .= " LIMIT ";');
123 $this->write( '$sql .= intval($limit);');
124 $this->write( 'if( $offset !== false ) {');
125 $this->write( '$sql .= " OFFSET " . intval($offset);');
129 $this->write('$q = $db->query($sql);');
130 $this->write('$q->result(false, MYSQL_NUM);');
132 $this->write('$fetched_columns_raw = $q->list_fields(true);');
134 $this->write('$fetched_columns = array();');
135 $this->write('foreach($fetched_columns_raw as $col) {');
136 $this->write('if(substr($col,0,%s) == %s) {', strlen($this->name
)+
1, $this->name
.'.');
137 $this->write('$fetched_columns[] = substr($col,%s);', strlen($this->name
)+
1);
138 $this->write('} else {');
139 $this->write('$fetched_columns[] = $col;');
143 $this->write('if($columns === false) {');
144 $this->write( '$columns = static::get_all_columns_list();');
147 $this->write('return new LivestatusSetIterator($q, $fetched_columns, $columns, $this->class);');
148 $this->finish_function();
152 * Generate the method map_name_to_backend for the object set
154 * @param $oset ORMObjectSetGenerator
156 public function generate_map_name_to_backend() {
157 $this->init_function('map_name_to_backend', array('name', 'prefix'), array('static'), array('prefix' => false));
158 $this->write('if($prefix === false) {');
159 $this->write('$prefix = %s;', $this->name
.'.');
161 foreach($this->structure
['structure'] as $field => $type ) {
162 $backend_field = $field;
163 if(isset($this->structure
['rename']) && isset($this->structure
['rename'][$field])) {
164 $backend_field = $this->structure
['rename'][$field];
166 if(is_array($type)) {
167 $subobjset_class = $type[0].'Set'.self
::$model_suffix;
168 $this->write('if(substr($name,0,%s) == %s) {', strlen($field)+
1, $field.'.');
169 $this->write('return '.$subobjset_class.'::map_name_to_backend(substr($name,%d),%s);', strlen($field)+
1, $type[1]);
172 $this->write('if($name == %s) {', $field);
173 $this->write('return $prefix.%s;',$backend_field);
177 $this->write('return false;');