db-attribute 2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ import collections, json
2
+
3
+ import db_attribute
4
+
5
+ db_class = db_attribute.db_class
6
+
7
+ class _NotSetMetaClass(type):
8
+ def __repr__(cls):
9
+ return cls.__name__
10
+
11
+ class NotSet(metaclass=_NotSetMetaClass):
12
+ pass
13
+
14
+ class MISSING(metaclass=_NotSetMetaClass):
15
+ pass
16
+
17
+ class Id:
18
+ def __init__(self, Id: int, cls_name=None):
19
+ self.Id = Id
20
+ self.cls_name = cls_name
21
+ def __repr__(self):
22
+ return f'{self.cls_name}(id={self.Id})' if self.cls_name else f'Any(id={self.Id})'
23
+
24
+ class Ids:
25
+ def __init__(self, Ids=None, cls_name=None):
26
+ if Ids is None:
27
+ Ids = []
28
+ self.set_ids = set(Ids)
29
+ self.list_ids = sorted(list(self.set_ids))
30
+ self.cls_name = cls_name
31
+ for i in range(len(self.list_ids)):
32
+ if not isinstance(self.list_ids[i], Id):
33
+ self.list_ids[i] = Id(self.list_ids[i], cls_name=cls_name)
34
+ self.set_ids = set(self.list_ids)
35
+ def __len__(self):
36
+ return len(self.list_ids)
37
+ def __bool__(self):
38
+ return bool(self.list_ids)
39
+ def __iter__(self):
40
+ return iter(self.list_ids)
41
+ def __repr__(self):
42
+ return f'{self.cls_name if self.cls_name else "Ids"}({[i.Id for i in self.list_ids]})'
43
+
44
+ class JsonType:
45
+ pass
46
+
47
+ class Factory:
48
+ def __init__(self, fabric):
49
+ self.fabric = fabric
50
+ def get_value(self):
51
+ return self.fabric()
52
+ def __call__(self):
53
+ return self.fabric()
54
+ def __repr__(self):
55
+ return 'FACTORY'
56
+
57
+ class DbField:
58
+ def __init__(self, default=MISSING, default_factory=MISSING, python_type=MISSING, mysql_type=MISSING, repr=True, init=True, **kwargs):
59
+ """Attention! python_type takes precedence over the data type specified in the annotation"""
60
+ self.default = default
61
+ self.default_factory = MISSING if default_factory is MISSING else Factory(default_factory)
62
+ self.python_type = python_type
63
+ self.mysql_type = mysql_type
64
+ self.repr = repr
65
+ self.init = init
66
+ def __repr__(self):
67
+ return f'DbField({", ".join([f"{i} = {self.__dict__[i]}" for i in self.__dict__ if self.__dict__[i] is not MISSING])})'
68
+
69
+ def get_default(self):
70
+ if self.default is not MISSING:
71
+ return self.default
72
+ if self.default_factory is not MISSING:
73
+ return self.default_factory.get_value()
74
+ return MISSING
75
+
76
+ class TableType:
77
+ def __init__(self, name_cls):
78
+ self.name_cls = name_cls
79
+ def __repr__(self):
80
+ return f'temp type of {self.name_cls} class'
81
+
82
+ class TableObject:
83
+ def __init__(self, name_cls, args=None, kwargs=None):
84
+ self.name_cls = name_cls
85
+ self.args = [] if args is None else args
86
+ self.kwargs = dict() if kwargs is None else kwargs
87
+ def __repr__(self):
88
+ return f'temp type of {self.name_cls} class'
89
+
90
+ class DictClasses:
91
+ """
92
+ DictClasses is used to store DbAttribute classes.
93
+ It replaces the TableType and TableObject classes, which use a string to define these classes.
94
+ Created DbContainer for classes (for saved in DbList, DbDict and other).
95
+ :argument data: main data store. Example: {'User': User, 'Book': Book}
96
+ """
97
+ def __init__(self):
98
+ self.data = dict()
99
+ self.needdata = collections.defaultdict(set)
100
+ self.db_containers = dict()
101
+
102
+ def add(self, cls):
103
+ self.data[cls.__name__] = cls
104
+ self.db_containers[cls.__name__] = _created_db_class(cls)
105
+ for othercls in self.needdata.get(cls.__name__, []):
106
+ self.replace(othercls)
107
+ if cls.__name__ in self.needdata:
108
+ del self.needdata[cls.__name__]
109
+ self.replace(cls)
110
+
111
+ def replace(self, cls):
112
+ temp = cls.__db_fields__
113
+ for nameattr in temp:
114
+ if isinstance(temp[nameattr].python_type, TableType):
115
+ if temp[nameattr].python_type.name_cls in self.data:
116
+ temp[nameattr].python_type = self.data[temp[nameattr].python_type.name_cls]
117
+ else:
118
+ self.needdata[temp[nameattr].python_type.name_cls].add(cls)
119
+ value = temp[nameattr].get_default()
120
+ if isinstance(value, TableObject):
121
+ if value.name_cls in self.data:
122
+ now_need_cls = self.data[value.name_cls]
123
+ now_need_args = value.args
124
+ now_need_kwargs = value.kwargs
125
+ temp[nameattr].default = MISSING
126
+ temp[nameattr].default_factory = Factory(lambda: now_need_cls(*now_need_args, **now_need_kwargs))
127
+ else:
128
+ self.needdata[value.name_cls].add(cls)
129
+
130
+ def _created_db_class(cls):
131
+ @db_class.DbClassDecorator
132
+ class ContainerDbAttribute(db_class.DbClass, cls, need_DbAttributeMetaclass=False, __repr_class_name__=cls.__name__):
133
+ def __init__(self, id: int = NotSet, *args, _use_db=False, _convert_arguments=True, _obj_dbattribute=None, _name_attribute=None, _first_container=None, **kwargs):
134
+ super().__init__(*args, _obj_dbattribute=_obj_dbattribute, _name_attribute=_name_attribute, _first_container=_first_container, _call_init=False, **kwargs)
135
+ object.__setattr__(self, 'id', id)
136
+
137
+ @classmethod
138
+ def __convert_to_db__(cls, obj: db_attribute.DbAttribute, _obj_dbattribute=None, _name_attribute=None, _first_container=None):
139
+ if isinstance(obj, int):
140
+ Id = obj
141
+ else:
142
+ Id = obj.id
143
+ return cls(id=Id, _use_db=True, _obj_dbattribute=_obj_dbattribute, _name_attribute=_name_attribute, _first_container=_first_container)
144
+
145
+ def dumps(self, _return_json=True):
146
+ if _return_json: return json.dumps({'t': f'ContainerDbAttribute_{cls.__name__}', 'i': self.id})
147
+ return {'t': f'ContainerDbAttribute_{cls.__name__}', 'i': self.id}
148
+
149
+ def copy(self):
150
+ return cls(id=self.id)
151
+
152
+ @classmethod
153
+ def _loads(cls, tempdata: dict, *, _obj_dbattribute=None, _name_attribute=None, _first_container=None):
154
+ return cls(id=tempdata['i'], _use_db=True, _obj_dbattribute=_obj_dbattribute, _name_attribute=_name_attribute, _first_container=_first_container)
155
+
156
+ ContainerDbAttribute.__name__ = f'ContainerDbAttribute_{cls.__name__}'
157
+
158
+ db_class.cheaker.add_db_class((cls, ContainerDbAttribute))
159
+ return ContainerDbAttribute
160
+
161
+ #dict_classes = DictClasses()
162
+
163
+ if __name__ == "__main__":
164
+ Field = DbField(default_factory=lambda:10)
165
+ print(Field.get_default())
166
+ """
167
+ class A:
168
+ b: DbAttributeType('B')
169
+ print(A.__annotations__, f'{dict_classes.data=} {dict_classes.needdata=}')
170
+ dict_classes.add(A)
171
+ print(A.__annotations__, f'{dict_classes.data=} {dict_classes.needdata=}')
172
+ class B:
173
+ a: DbAttributeType('A')
174
+ print(A.__annotations__, B.__annotations__, f'{dict_classes.data=} {dict_classes.needdata=}')
175
+ dict_classes.add(B)
176
+ print(A.__annotations__, B.__annotations__, f'{dict_classes.data=} {dict_classes.needdata=}')
177
+ """
178
+
@@ -0,0 +1,365 @@
1
+ import functools
2
+ import json
3
+ import orjson
4
+ import collections
5
+
6
+ from mysql.connector import errorcode
7
+
8
+ import db_attribute.db_class as db_class
9
+ import db_attribute.db_types as dbtypes
10
+ import db_attribute
11
+
12
+ def get_default_value_from_type(attribute_type):
13
+ if attribute_type == str:
14
+ return {'status_code': 200, 'data': ''}
15
+ if attribute_type == int:
16
+ return {'status_code': 200, 'data': '0'}
17
+ if attribute_type == float:
18
+ return {'status_code': 200, 'data': '0.0'}
19
+ if attribute_type == bool:
20
+ return {'status_code': 200, 'data': 'False'}
21
+ if attribute_type is dbtypes.JsonType:
22
+ return {'status_code': 200, 'data': json.dumps(json.dumps(dict()))}
23
+ return {'status_code': 300}
24
+
25
+ def convert_attribute_type_to_mysql_type(attribute_type, len_varchar=50):
26
+ if attribute_type == str:
27
+ return {'status_code': 200, 'data': f'varchar({len_varchar})'}
28
+ if attribute_type == int or issubclass(attribute_type, db_attribute.DbAttribute):
29
+ return {'status_code': 200, 'data': f'bigint'}
30
+ if attribute_type == float or attribute_type == bool:
31
+ return {'status_code': 200, 'data': attribute_type.__name__.upper()}
32
+ if db_class.cheaker.this_db_attribute_support_class(attribute_type, this_is_cls=True) or db_class.cheaker.this_support_class(attribute_type, this_is_cls=True) or attribute_type is dbtypes.JsonType:
33
+ return {'status_code': 200, 'data': 'json'}
34
+ return {'status_code': 300}
35
+
36
+ def convert_attribute_value_to_mysql_value(attribute_value, attribute_type):
37
+ if attribute_type in (int, float, bool):
38
+ return {'status_code': 200, 'data': f'{attribute_value}'}
39
+ if attribute_type == str:
40
+ return {'status_code': 200, 'data': json.dumps(attribute_value, ensure_ascii=False)}
41
+ if attribute_type is dbtypes.JsonType:
42
+ return {'status_code': 200, 'data': json.dumps(json.dumps(attribute_value))}
43
+ if issubclass(attribute_type, db_attribute.discriptor.ConditionCore):
44
+ return {'status_code': 200, 'data': attribute_value._get_condition_repr()}
45
+ if issubclass(attribute_type, db_attribute.DbAttribute):
46
+ if type(attribute_value) is int:
47
+ return {'status_code': 200, 'data': f'{attribute_value}'}
48
+ return {'status_code': 200, 'data': f'{object.__getattribute__(attribute_value, 'id')}'}
49
+ if db_class.cheaker.this_db_attribute_support_class(attribute_type, this_is_cls=True) or db_class.cheaker.this_support_class(attribute_type, this_is_cls=True):
50
+ if db_class.cheaker.this_db_attribute_support_class(attribute_value):
51
+ return {'status_code': 200, 'data': f'CAST({json.dumps(attribute_value.dumps(), ensure_ascii=False)} AS JSON)'}
52
+ return {'status_code': 200, 'data': f'CAST({json.dumps(db_class.cheaker.create_db_class(attribute_value).dumps(), ensure_ascii=False)} AS JSON)'}
53
+ return {'status_code': 300}
54
+
55
+ def convert_mysql_value_to_attribute_value(mysql_value, attribute_type, _obj_dbattribute=None, attribute_name=None):
56
+ if attribute_type in (int, float, str):
57
+ return {'status_code': 200, 'data': mysql_value}
58
+ if attribute_type == bool:
59
+ return {'status_code': 200, 'data': True if mysql_value else False}
60
+ if attribute_type is dbtypes.JsonType:
61
+ return {'status_code': 200, 'data': orjson.loads(mysql_value)}
62
+ if issubclass(attribute_type, db_attribute.DbAttribute):
63
+ return {'status_code': 200, 'data': attribute_type.get(id=mysql_value)}
64
+ if db_class.cheaker.this_support_class(attribute_type, this_is_cls=True) or db_class.cheaker.this_db_attribute_support_class(attribute_type, this_is_cls=True):
65
+ return {'status_code': 200, 'data': db_class.DbClass.loads(mysql_value, _obj_dbattribute=_obj_dbattribute, _name_attribute=attribute_name)}
66
+ return {'status_code': 300}
67
+
68
+ def sql_decorator(func_d=None, /, standart_return=None):
69
+ def active_decorator(func):
70
+ @functools.wraps(func)
71
+ def method_wrapper(self, *args, **kwargs):
72
+ if self.connobj.notconn:
73
+ if standart_return:
74
+ return standart_return
75
+ return {'status_code': 100}
76
+ res = func(self, *args, **kwargs)
77
+ return res
78
+ return method_wrapper
79
+ if func_d is None:
80
+ return active_decorator
81
+ return active_decorator(func_d)
82
+
83
+ def get_table_name(class_name:str, attribute_name:str):
84
+ if ' ' in class_name:
85
+ raise Exception(f'The "{class_name}" class has the space (" ") in the name')
86
+ if ' ' in attribute_name:
87
+ raise Exception(f'The "{attribute_name}" attribute has the space (" ") in the name')
88
+ return f'cls {class_name} atr {attribute_name}'.lower()
89
+
90
+ def get_id_table_name(class_name:str):
91
+ return f'cls {class_name} ids'.lower()
92
+
93
+ def screening(name, db_name="MySQL"):
94
+ if db_name == "MySQL":
95
+ return f'`{name}`'
96
+ return f'"{name}"'
97
+
98
+ class Db_work:
99
+ def __init__(self, connobj, sittings_for_mysql_types=None):
100
+ """
101
+ :param connobj: obj of connector.Connection
102
+ :param sittings_for_mysql_types: (at this moment not used) example: {str: 'VARCHAR(255)', int: 'BIGINT', bytes: 'BLOB'}
103
+ """
104
+ self.connobj = connobj
105
+ self.sittings_for_mysql_types = {str: 'VARCHAR(255)', int: 'BIGINT', bytes: 'BLOB'}
106
+ if isinstance(sittings_for_mysql_types, dict):
107
+ self.sittings_for_mysql_types |= sittings_for_mysql_types
108
+ self.tables = self.get_tables_list()['data']
109
+ self.class_names = self.get_class_names_list()
110
+
111
+ def get_class_names_list(self):
112
+ Res = collections.defaultdict(list)
113
+ for i in self.tables:
114
+ try:
115
+ temp = i.split()
116
+ if temp[0] == 'cls' and temp[2] == 'atr':
117
+ Res[temp[1]].append(i)
118
+ except:
119
+ pass
120
+ return dict(Res)
121
+
122
+ @sql_decorator()
123
+ def get_tables_list(self):
124
+ self.connobj.cur.execute(f"""show tables""")
125
+ return {'status_code': 200, 'data': {i[0] for i in self.connobj.cur.fetchall()}}
126
+
127
+ @sql_decorator
128
+ def _create_table(self, table_name: str, attributes: list[tuple[str, str]]):
129
+ if table_name.lower() in self.tables:
130
+ return {'status_code': 301}
131
+ screening_table_name = screening(table_name, self.connobj.sql_name)
132
+ self.connobj.cur.execute(f"""CREATE TABLE {screening_table_name} (id BIGINT PRIMARY KEY AUTO_INCREMENT{', ' if attributes else ''}{', '.join((f'{attribute[0]} {attribute[1]}' for attribute in attributes))})""")
133
+ self.connobj.conn.commit()
134
+ self.tables = self.get_tables_list()['data']
135
+ self.class_names = self.get_class_names_list()
136
+ return {'status_code': 200}
137
+
138
+ @sql_decorator
139
+ def _create_id_table(self, table_name: str):
140
+ if table_name.lower() in self.tables:
141
+ return {'status_code': 301}
142
+ scr_table_name = screening(table_name, self.connobj.sql_name)
143
+ self.connobj.cur.execute(f"""CREATE TABLE {scr_table_name} (id BIGINT PRIMARY KEY AUTO_INCREMENT)""")
144
+ self.connobj.conn.commit()
145
+ self.tables = self.get_tables_list()['data']
146
+ self.class_names = self.get_class_names_list()
147
+ return {'status_code': 200}
148
+
149
+ @sql_decorator
150
+ def _deleate_table(self, table_name: str, ignore_302:bool=False):
151
+ if table_name.lower() not in self.tables:
152
+ if ignore_302:
153
+ return {'status_code': 200}
154
+ return {'status_code': 302}
155
+ scr_table_name = screening(table_name, self.connobj.sql_name)
156
+ self.connobj.cur.execute(f"""DROP TABLE {scr_table_name}""")
157
+ self.connobj.conn.commit()
158
+ self.tables = self.get_tables_list()['data']
159
+ self.class_names = self.get_class_names_list()
160
+ return {'status_code': 200}
161
+
162
+ @sql_decorator
163
+ def _get_type_data_table(self, table_name: str):
164
+ if table_name not in self.tables:
165
+ return {'status_code': 302}
166
+ self.connobj.cur.execute(f"""SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'data' AND TABLE_SCHEMA = '{self.connobj.database}' AND TABLE_NAME = '{table_name}';""")
167
+ return {'status_code': 200, 'data': self.connobj.cur.fetchall()[-1][0]}
168
+
169
+ @sql_decorator
170
+ def _get_values_by_id(self, table_name:str, ID:int, operator:str= "=", ignore_302:bool=False):
171
+ if table_name not in self.tables:
172
+ if ignore_302:
173
+ return {'status_code': 200, 'data': []}
174
+ return {'status_code': 302}
175
+ scr_table_name = screening(table_name, self.connobj.sql_name)
176
+ self.connobj.cur.execute(f"""select * from {scr_table_name} where id {operator} {ID}""")
177
+ return {'status_code': 200, 'data': [i[-1] for i in self.connobj.cur.fetchall()]}
178
+
179
+ @sql_decorator
180
+ def _get_ids_by_value(self, table_name:str, value, operator:str= "=", ignore_302:bool=False):
181
+ if table_name not in self.tables:
182
+ if ignore_302:
183
+ return {'status_code': 200, 'data': []}
184
+ return {'status_code': 302}
185
+ scr_table_name = screening(table_name, self.connobj.sql_name)
186
+ self.connobj.cur.execute(f"""select id from {scr_table_name} where data {operator} {value}""")
187
+ return {'status_code': 200, 'data': {i[0] for i in self.connobj.cur.fetchall()}}
188
+
189
+ @sql_decorator
190
+ def _get_all_ids(self, table_name: str, ignore_302: bool = False):
191
+ if table_name not in self.tables:
192
+ if ignore_302:
193
+ return {'status_code': 200, 'data': []}
194
+ return {'status_code': 302}
195
+ scr_table_name = screening(table_name, self.connobj.sql_name)
196
+ self.connobj.cur.execute(f"""select id from {scr_table_name}""")
197
+ return {'status_code': 200, 'data': {i[0] for i in self.connobj.cur.fetchall()}}
198
+
199
+ @sql_decorator
200
+ def _get_ids_by_condition(self, class_name:str, condition:str, ignore_302:bool=False):
201
+ if class_name not in self.class_names:
202
+ if ignore_302:
203
+ return {'status_code': 200, 'data': []}
204
+ return {'status_code': 302}
205
+ id_table = get_id_table_name(class_name)
206
+ scr_id_table = screening(id_table, self.connobj.sql_name)
207
+ scr_id = screening('id', self.connobj.sql_name)
208
+ temp = [screening(i, self.connobj.sql_name) for i in self.class_names[class_name]]
209
+ self.connobj.cur.execute(f"""select {scr_id_table}.{scr_id} from {scr_id_table} {' '.join((f'left join {i} on {scr_id_table}.{scr_id} = {i}.{scr_id}' for i in temp))} where {condition}""")
210
+ return {'status_code': 200, 'data': {i[0] for i in self.connobj.cur.fetchall()}}
211
+
212
+ @sql_decorator
213
+ def _del_value_by_id(self, table_name:str, ID:int, ignore_302:bool=False):
214
+ if table_name not in self.tables:
215
+ if ignore_302:
216
+ return {'status_code': 200}
217
+ return {'status_code': 302}
218
+ scr_table_name = screening(table_name, self.connobj.sql_name)
219
+ self.connobj.cur.execute(f"""delete from {scr_table_name} where id={ID}""")
220
+ self.connobj.conn.commit()
221
+ return {'status_code': 200}
222
+
223
+ @sql_decorator
224
+ def _add_value_by_id(self, table_name:str, ID:int, value, ignore_302:bool=False):
225
+ try:
226
+ scr_table_name = screening(table_name, self.connobj.sql_name)
227
+ self.connobj.cur.execute(f"""insert ignore into {scr_table_name} (id, data) values ({ID}, {value}) on duplicate key update data=VALUES(data)""")
228
+ self.connobj.conn.commit()
229
+ except Exception as e:
230
+ if e.errno == errorcode.ER_NO_SUCH_TABLE:
231
+ return {'status_code': 200} if ignore_302 else {'status_code': 302}
232
+ raise e
233
+ return {'status_code': 200}
234
+
235
+ @sql_decorator
236
+ def _add_id(self, table_name:str, ID:int, ignore_302:bool=False):
237
+ try:
238
+ scr_table_name = screening(table_name, self.connobj.sql_name)
239
+ self.connobj.cur.execute(f"""insert into {scr_table_name} (id) values ({ID}) on duplicate key update id=VALUES(id)""")
240
+ self.connobj.conn.commit()
241
+ except Exception as e:
242
+ if e.errno == errorcode.ER_NO_SUCH_TABLE:
243
+ return {'status_code': 200} if ignore_302 else {'status_code': 302}
244
+ raise e
245
+ return {'status_code': 200}
246
+
247
+ @sql_decorator
248
+ def _get_new_id(self, table_name:str):
249
+ try:
250
+ scr_table_name = screening(table_name, self.connobj.sql_name)
251
+ self.connobj.cur.execute(f"INSERT INTO {scr_table_name} () VALUES ()")
252
+ next_id = self.connobj.cur.lastrowid
253
+ self.connobj.conn.commit()
254
+ except Exception as e:
255
+ if e.errno == errorcode.ER_NO_SUCH_TABLE:
256
+ return {'status_code': 302}
257
+ raise e
258
+ return {'status_code': 200, 'data': next_id}
259
+
260
+ def create_attribute_table(self, class_name: str, attribute_name: str, attribute_type=None, _cls_dbattribute=None, len_varchar:int=50):
261
+ """
262
+ create attribute table
263
+ :param class_name: name of class attribute (obj.__class__.__name__)
264
+ :param attribute_name: name of attribute, example: 'name', 'id', 'nickname', 'password_hash'
265
+ :param attribute_type: type of attribute (type(obj)), example: str, DbList, int, bool, DbSet, dbtypes.JsonType (for create DbList, DbSet use db_class.cheaker.create_one_db_class)
266
+ :param _cls_dbattribute: db_attribute cls, used if attribute_type is None
267
+ :param len_varchar: len for string attributes, example: with len_varchar=5, attribute name='VeryLongName' convert to 'VeryL'
268
+ :return: {'status_code': 300 | 200 | 100} (for 'status_code' read in connector)
269
+ """
270
+ table_name = get_table_name(class_name=class_name, attribute_name=attribute_name)
271
+ if attribute_type is None:
272
+ attribute_type = object.__getattribute__(_cls_dbattribute, '__db_fields__')[attribute_name].python_type
273
+ temp_data = convert_attribute_type_to_mysql_type(attribute_type=attribute_type, len_varchar=len_varchar)
274
+ if temp_data['status_code'] != 200: return temp_data
275
+ attribute_table_type = temp_data['data']
276
+ temp_data = self._create_table(table_name=table_name, attributes=[('data', attribute_table_type)])
277
+ if temp_data['status_code'] != 200: return temp_data
278
+ return {'status_code': 200}
279
+
280
+ def create_id_table(self, class_name: str):
281
+ return self._create_id_table(get_id_table_name(class_name=class_name))
282
+
283
+ def add_attribute_value(self, class_name: str, attribute_name: str, ID:int, data, attribute_type=None, _cls_dbattribute=None, ignore_302:bool=False):
284
+ if attribute_type is None:
285
+ attribute_type = object.__getattribute__(_cls_dbattribute, '__db_fields__')[attribute_name].python_type
286
+ temp_data = convert_attribute_value_to_mysql_value(data, attribute_type=attribute_type)
287
+ if temp_data['status_code'] != 200: return temp_data
288
+ value = temp_data['data']
289
+ table_name = get_table_name(class_name=class_name, attribute_name=attribute_name)
290
+ return self._add_value_by_id(table_name=table_name, ID=ID, value=value, ignore_302=ignore_302)
291
+
292
+ def add_id(self, class_name: str, ID:int, ignore_302:bool=False):
293
+ return self._add_id(table_name=get_id_table_name(class_name), ID=ID, ignore_302=ignore_302)
294
+
295
+ def get_new_id(self, class_name: str):
296
+ return self._get_new_id(table_name=get_id_table_name(class_name))
297
+
298
+ def get_attribute_value(self, class_name: str, attribute_name: str, ID:int, attribute_type=None, _obj_dbattribute=None):
299
+ table_name = get_table_name(class_name=class_name, attribute_name=attribute_name)
300
+ temp_data = self._get_values_by_id(table_name=table_name, ID=ID)
301
+ if temp_data['status_code'] != 200: return temp_data
302
+ if len(temp_data['data']) == 0: return {'status_code': 304}
303
+ value = temp_data['data'][0]
304
+ if attribute_type is None:
305
+ attribute_type = object.__getattribute__(_obj_dbattribute, '__db_fields__')[attribute_name].python_type
306
+ return convert_mysql_value_to_attribute_value(value, attribute_type=attribute_type, _obj_dbattribute=_obj_dbattribute, attribute_name=attribute_name)
307
+
308
+ def get_all_ids(self, class_name: str, ignore_302:bool=False):
309
+ return self._get_all_ids(table_name=get_id_table_name(class_name=class_name), ignore_302=ignore_302)
310
+
311
+ def del_attribute_value(self, class_name: str, attribute_name: str, ID:int, ignore_302:bool=False):
312
+ table_name = get_table_name(class_name=class_name, attribute_name=attribute_name)
313
+ return self._del_value_by_id(table_name=table_name, ID=ID, ignore_302=ignore_302)
314
+
315
+ def found_ids_by_value(self, class_name: str, attribute_name: str, data, attribute_type=None, _cls_dbattribute=None, operator: str="=", ignore_302:bool=False):
316
+ """
317
+ :param class_name: ex: 'User'
318
+ :param attribute_name: ex: 'name'/'age'
319
+ :param data: any data, ex: 10 / {3, 5, 6} / 'Bob'
320
+ :param attribute_type: ex: int, bool, list, User (Db attribute type)
321
+ :param _cls_dbattribute: User
322
+ :param operator: '=' / '!=' / '<>' / '<' / '>' / '>=' / '<=' / 'Like'
323
+ :param ignore_302: bool, if true, ignore 302 error, return 200 and empty data
324
+ :return: set of id's
325
+ """
326
+ if attribute_type is None:
327
+ attribute_type = object.__getattribute__(_cls_dbattribute, '__db_fields__')[attribute_name].python_type
328
+ temp_data = convert_attribute_value_to_mysql_value(data, attribute_type=attribute_type)
329
+ if temp_data['status_code'] != 200: return temp_data
330
+ value = temp_data['data']
331
+ table_name = get_table_name(class_name=class_name, attribute_name=attribute_name)
332
+ return self._get_ids_by_value(table_name=table_name, value=value, operator=operator, ignore_302=ignore_302)
333
+
334
+ def found_ids_by_condition(self, class_name: str, condition: str, ignore_302:bool=False):
335
+ return self._get_ids_by_condition(class_name=class_name.lower(), condition=condition, ignore_302=ignore_302)
336
+
337
+ def cheak_exists_attribute_table(self, class_name: str, attribute_name: str):
338
+ return get_table_name(class_name, attribute_name) in self.tables
339
+
340
+ def cheak_exists_id_table(self, class_name: str):
341
+ return get_id_table_name(class_name) in self.tables
342
+
343
+
344
+ if __name__ == '__main__':
345
+ from config import host, user, password, database
346
+ import connector
347
+
348
+ connect_obj = connector.Connection(host=host, user=user, password=password, database=database)
349
+ db_work_obj = Db_work(connect_obj)
350
+ #print(db_work_obj.class_names)
351
+ #print(db_work_obj.tables)
352
+ #db_work_obj.create_attribute_table('User', 'name', str)
353
+ #db_work_obj.add_attribute_value('User', 'name', 10, 'Bob', str)
354
+ #print(db_work_obj.get_attribute_value('User', 'name', 10, str))
355
+ print(db_work_obj.tables)
356
+ print(db_work_obj.class_names)
357
+ #db_work_obj._deleate_table('cls dbattributemetaclass ids')
358
+ #for i in db_work_obj.tables:
359
+ # db_work_obj._deleate_table(i)
360
+ # print(i)
361
+
362
+ #db_work_obj.deleate_table('cls_a_atr_b_obj')
363
+
364
+ #db_work_obj.update_value_by_id(table_name='cls_user_atr_age', ID=12, value=10, cheak_exists_value=False)
365
+