1 
2 #ifdef HAVE_CONFIG_H
3 #include "../../../../../ext_config.h"
4 #endif
5 
6 #include <php.h>
7 #include "../../../../../php_ext.h"
8 #include "../../../../../ext.h"
9 
10 #include <Zend/zend_operators.h>
11 #include <Zend/zend_exceptions.h>
12 #include <Zend/zend_interfaces.h>
13 
14 #include "kernel/main.h"
15 #include "kernel/fcall.h"
16 #include "kernel/memory.h"
17 #include "kernel/operators.h"
18 #include "kernel/concat.h"
19 #include "kernel/exception.h"
20 #include "kernel/object.h"
21 #include "kernel/array.h"
22 
23 
24 /**
25  * Phalcon\Mvc\Model\MetaData\Strategy\Introspection
26  *
27  * Queries the table meta-data in order to introspect the model's metadata
28  */
ZEPHIR_INIT_CLASS(Phalcon_Mvc_Model_MetaData_Strategy_Introspection)29 ZEPHIR_INIT_CLASS(Phalcon_Mvc_Model_MetaData_Strategy_Introspection) {
30 
31 	ZEPHIR_REGISTER_CLASS(Phalcon\\Mvc\\Model\\MetaData\\Strategy, Introspection, phalcon, mvc_model_metadata_strategy_introspection, phalcon_mvc_model_metadata_strategy_introspection_method_entry, 0);
32 
33 	zend_class_implements(phalcon_mvc_model_metadata_strategy_introspection_ce TSRMLS_CC, 1, phalcon_mvc_model_metadata_strategyinterface_ce);
34 	return SUCCESS;
35 
36 }
37 
38 /**
39  * The meta-data is obtained by reading the column descriptions from the database information schema
40  */
PHP_METHOD(Phalcon_Mvc_Model_MetaData_Strategy_Introspection,getMetaData)41 PHP_METHOD(Phalcon_Mvc_Model_MetaData_Strategy_Introspection, getMetaData) {
42 
43 	zend_bool _16$$9;
44 	HashTable *_8;
45 	HashPosition _7;
46 	zend_long ZEPHIR_LAST_CALL_STATUS;
47 	zval *model, *dependencyInjector, *schema = NULL, *table = NULL, *readConnection = NULL, *columns = NULL, *attributes = NULL, *primaryKeys = NULL, *nonPrimaryKeys = NULL, *completeTable = NULL, *numericTyped = NULL, *notNull = NULL, *fieldTypes = NULL, *automaticDefault = NULL, *identityField = NULL, *fieldBindTypes = NULL, *defaultValues = NULL, *column = NULL, *fieldName = NULL, *defaultValue = NULL, *emptyStringValues = NULL, *_0 = NULL, **_9, *_1$$3, *_2$$3, *_3$$3, *_4$$6, *_5$$6, *_6$$6, *_10$$9 = NULL, *_11$$9 = NULL, *_12$$9 = NULL, *_13$$9 = NULL, *_14$$9 = NULL, *_15$$9 = NULL, *_17$$9 = NULL, *_18$$15 = NULL;
48 
49 	ZEPHIR_MM_GROW();
50 	zephir_fetch_params(1, 2, 0, &model, &dependencyInjector);
51 
52 
53 
54 	ZEPHIR_CALL_METHOD(&schema, model, "getschema", NULL, 0);
55 	zephir_check_call_status();
56 	ZEPHIR_CALL_METHOD(&table, model, "getsource", NULL, 0);
57 	zephir_check_call_status();
58 	ZEPHIR_CALL_METHOD(&readConnection, model, "getreadconnection", NULL, 0);
59 	zephir_check_call_status();
60 	ZEPHIR_CALL_METHOD(&_0, readConnection, "tableexists", NULL, 0, table, schema);
61 	zephir_check_call_status();
62 	if (!(zephir_is_true(_0))) {
63 		if (zephir_is_true(schema)) {
64 			ZEPHIR_INIT_VAR(completeTable);
65 			ZEPHIR_CONCAT_VSV(completeTable, schema, "'.'", table);
66 		} else {
67 			ZEPHIR_CPY_WRT(completeTable, table);
68 		}
69 		ZEPHIR_INIT_VAR(_1$$3);
70 		object_init_ex(_1$$3, phalcon_mvc_model_exception_ce);
71 		ZEPHIR_INIT_VAR(_2$$3);
72 		zephir_get_class(_2$$3, model, 0 TSRMLS_CC);
73 		ZEPHIR_INIT_VAR(_3$$3);
74 		ZEPHIR_CONCAT_SVSV(_3$$3, "Table '", completeTable, "' doesn't exist in database when dumping meta-data for ", _2$$3);
75 		ZEPHIR_CALL_METHOD(NULL, _1$$3, "__construct", NULL, 9, _3$$3);
76 		zephir_check_call_status();
77 		zephir_throw_exception_debug(_1$$3, "phalcon/mvc/model/metadata/strategy/introspection.zep", 68 TSRMLS_CC);
78 		ZEPHIR_MM_RESTORE();
79 		return;
80 	}
81 	ZEPHIR_CALL_METHOD(&columns, readConnection, "describecolumns", NULL, 0, table, schema);
82 	zephir_check_call_status();
83 	if (!(zephir_fast_count_int(columns TSRMLS_CC))) {
84 		if (zephir_is_true(schema)) {
85 			ZEPHIR_INIT_NVAR(completeTable);
86 			ZEPHIR_CONCAT_VSV(completeTable, schema, "'.'", table);
87 		} else {
88 			ZEPHIR_CPY_WRT(completeTable, table);
89 		}
90 		ZEPHIR_INIT_VAR(_4$$6);
91 		object_init_ex(_4$$6, phalcon_mvc_model_exception_ce);
92 		ZEPHIR_INIT_VAR(_5$$6);
93 		zephir_get_class(_5$$6, model, 0 TSRMLS_CC);
94 		ZEPHIR_INIT_VAR(_6$$6);
95 		ZEPHIR_CONCAT_SVSV(_6$$6, "Cannot obtain table columns for the mapped source '", completeTable, "' used in model ", _5$$6);
96 		ZEPHIR_CALL_METHOD(NULL, _4$$6, "__construct", NULL, 9, _6$$6);
97 		zephir_check_call_status();
98 		zephir_throw_exception_debug(_4$$6, "phalcon/mvc/model/metadata/strategy/introspection.zep", 88 TSRMLS_CC);
99 		ZEPHIR_MM_RESTORE();
100 		return;
101 	}
102 	ZEPHIR_INIT_VAR(attributes);
103 	array_init(attributes);
104 	ZEPHIR_INIT_VAR(primaryKeys);
105 	array_init(primaryKeys);
106 	ZEPHIR_INIT_VAR(nonPrimaryKeys);
107 	array_init(nonPrimaryKeys);
108 	ZEPHIR_INIT_VAR(numericTyped);
109 	array_init(numericTyped);
110 	ZEPHIR_INIT_VAR(notNull);
111 	array_init(notNull);
112 	ZEPHIR_INIT_VAR(fieldTypes);
113 	array_init(fieldTypes);
114 	ZEPHIR_INIT_VAR(fieldBindTypes);
115 	array_init(fieldBindTypes);
116 	ZEPHIR_INIT_VAR(automaticDefault);
117 	array_init(automaticDefault);
118 	ZEPHIR_INIT_VAR(identityField);
119 	ZVAL_BOOL(identityField, 0);
120 	ZEPHIR_INIT_VAR(defaultValues);
121 	array_init(defaultValues);
122 	ZEPHIR_INIT_VAR(emptyStringValues);
123 	array_init(emptyStringValues);
124 	zephir_is_iterable(columns, &_8, &_7, 0, 0, "phalcon/mvc/model/metadata/strategy/introspection.zep", 165);
125 	for (
126 	  ; zend_hash_get_current_data_ex(_8, (void**) &_9, &_7) == SUCCESS
127 	  ; zend_hash_move_forward_ex(_8, &_7)
128 	) {
129 		ZEPHIR_GET_HVALUE(column, _9);
130 		ZEPHIR_CALL_METHOD(&fieldName, column, "getname", NULL, 0);
131 		zephir_check_call_status();
132 		zephir_array_append(&attributes, fieldName, PH_SEPARATE, "phalcon/mvc/model/metadata/strategy/introspection.zep", 109);
133 		ZEPHIR_CALL_METHOD(&_10$$9, column, "isprimary", NULL, 0);
134 		zephir_check_call_status();
135 		if (ZEPHIR_IS_TRUE_IDENTICAL(_10$$9)) {
136 			zephir_array_append(&primaryKeys, fieldName, PH_SEPARATE, "phalcon/mvc/model/metadata/strategy/introspection.zep", 115);
137 		} else {
138 			zephir_array_append(&nonPrimaryKeys, fieldName, PH_SEPARATE, "phalcon/mvc/model/metadata/strategy/introspection.zep", 117);
139 		}
140 		ZEPHIR_CALL_METHOD(&_11$$9, column, "isnumeric", NULL, 0);
141 		zephir_check_call_status();
142 		if (ZEPHIR_IS_TRUE_IDENTICAL(_11$$9)) {
143 			zephir_array_update_zval(&numericTyped, fieldName, &ZEPHIR_GLOBAL(global_true), PH_COPY | PH_SEPARATE);
144 		}
145 		ZEPHIR_CALL_METHOD(&_12$$9, column, "isnotnull", NULL, 0);
146 		zephir_check_call_status();
147 		if (ZEPHIR_IS_TRUE_IDENTICAL(_12$$9)) {
148 			zephir_array_append(&notNull, fieldName, PH_SEPARATE, "phalcon/mvc/model/metadata/strategy/introspection.zep", 131);
149 		}
150 		ZEPHIR_CALL_METHOD(&_13$$9, column, "isautoincrement", NULL, 0);
151 		zephir_check_call_status();
152 		if (ZEPHIR_IS_TRUE_IDENTICAL(_13$$9)) {
153 			ZEPHIR_CPY_WRT(identityField, fieldName);
154 		}
155 		ZEPHIR_CALL_METHOD(&_14$$9, column, "gettype", NULL, 0);
156 		zephir_check_call_status();
157 		zephir_array_update_zval(&fieldTypes, fieldName, &_14$$9, PH_COPY | PH_SEPARATE);
158 		ZEPHIR_CALL_METHOD(&_15$$9, column, "getbindtype", NULL, 0);
159 		zephir_check_call_status();
160 		zephir_array_update_zval(&fieldBindTypes, fieldName, &_15$$9, PH_COPY | PH_SEPARATE);
161 		ZEPHIR_CALL_METHOD(&defaultValue, column, "getdefault", NULL, 0);
162 		zephir_check_call_status();
163 		_16$$9 = Z_TYPE_P(defaultValue) != IS_NULL;
164 		if (!(_16$$9)) {
165 			ZEPHIR_CALL_METHOD(&_17$$9, column, "isnotnull", NULL, 0);
166 			zephir_check_call_status();
167 			_16$$9 = ZEPHIR_IS_FALSE_IDENTICAL(_17$$9);
168 		}
169 		if (_16$$9) {
170 			ZEPHIR_CALL_METHOD(&_18$$15, column, "isautoincrement", NULL, 0);
171 			zephir_check_call_status();
172 			if (!(zephir_is_true(_18$$15))) {
173 				zephir_array_update_zval(&defaultValues, fieldName, &defaultValue, PH_COPY | PH_SEPARATE);
174 			}
175 		}
176 	}
177 	zephir_create_array(return_value, 12, 0 TSRMLS_CC);
178 	zephir_array_update_long(&return_value, 0, &attributes, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
179 	zephir_array_update_long(&return_value, 1, &primaryKeys, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
180 	zephir_array_update_long(&return_value, 2, &nonPrimaryKeys, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
181 	zephir_array_update_long(&return_value, 3, &notNull, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
182 	zephir_array_update_long(&return_value, 4, &fieldTypes, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
183 	zephir_array_update_long(&return_value, 5, &numericTyped, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
184 	zephir_array_update_long(&return_value, 8, &identityField, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
185 	zephir_array_update_long(&return_value, 9, &fieldBindTypes, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
186 	zephir_array_update_long(&return_value, 10, &automaticDefault, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
187 	zephir_array_update_long(&return_value, 11, &automaticDefault, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
188 	zephir_array_update_long(&return_value, 12, &defaultValues, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
189 	zephir_array_update_long(&return_value, 13, &emptyStringValues, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
190 	RETURN_MM();
191 
192 }
193 
194 /**
195  * Read the model's column map, this can't be inferred
196  */
PHP_METHOD(Phalcon_Mvc_Model_MetaData_Strategy_Introspection,getColumnMaps)197 PHP_METHOD(Phalcon_Mvc_Model_MetaData_Strategy_Introspection, getColumnMaps) {
198 
199 	HashTable *_1$$3;
200 	HashPosition _0$$3;
201 	zend_long ZEPHIR_LAST_CALL_STATUS;
202 	zval *model, *dependencyInjector, *orderedColumnMap = NULL, *userColumnMap = NULL, *reversedColumnMap = NULL, *name = NULL, *userName = NULL, **_2$$3;
203 
204 	ZEPHIR_MM_GROW();
205 	zephir_fetch_params(1, 2, 0, &model, &dependencyInjector);
206 
207 
208 
209 	ZEPHIR_INIT_VAR(orderedColumnMap);
210 	ZVAL_NULL(orderedColumnMap);
211 	ZEPHIR_INIT_VAR(reversedColumnMap);
212 	ZVAL_NULL(reversedColumnMap);
213 	if ((zephir_method_exists_ex(model, SS("columnmap") TSRMLS_CC) == SUCCESS)) {
214 		ZEPHIR_CALL_METHOD(&userColumnMap, model, "columnmap", NULL, 0);
215 		zephir_check_call_status();
216 		if (Z_TYPE_P(userColumnMap) != IS_ARRAY) {
217 			ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "columnMap() not returned an array", "phalcon/mvc/model/metadata/strategy/introspection.zep", 198);
218 			return;
219 		}
220 		ZEPHIR_INIT_NVAR(reversedColumnMap);
221 		array_init(reversedColumnMap);
222 		ZEPHIR_CPY_WRT(orderedColumnMap, userColumnMap);
223 		zephir_is_iterable(userColumnMap, &_1$$3, &_0$$3, 0, 0, "phalcon/mvc/model/metadata/strategy/introspection.zep", 205);
224 		for (
225 		  ; zend_hash_get_current_data_ex(_1$$3, (void**) &_2$$3, &_0$$3) == SUCCESS
226 		  ; zend_hash_move_forward_ex(_1$$3, &_0$$3)
227 		) {
228 			ZEPHIR_GET_HMKEY(name, _1$$3, _0$$3);
229 			ZEPHIR_GET_HVALUE(userName, _2$$3);
230 			zephir_array_update_zval(&reversedColumnMap, userName, &name, PH_COPY | PH_SEPARATE);
231 		}
232 	}
233 	zephir_create_array(return_value, 2, 0 TSRMLS_CC);
234 	zephir_array_fast_append(return_value, orderedColumnMap);
235 	zephir_array_fast_append(return_value, reversedColumnMap);
236 	RETURN_MM();
237 
238 }
239 
240