rda-python-common 2.0.0__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,299 @@
1
+ #
2
+ ###############################################################################
3
+ #
4
+ # Title : PgSplit.py -- PostgreSQL DataBase Interface foe table wfile
5
+ # Author : Zaihua Ji, zji@ucar.edu
6
+ # Date : 09/010/2024
7
+ # 2025-01-10 transferred to package rda_python_common from
8
+ # https://github.com/NCAR/rßda-shared-libraries.git
9
+ # Purpose : Python library module to handle query and manß ipulate table wfile
10
+ #
11
+ # Github : https://github.com/NCAR/rda-python-common.git
12
+ #
13
+ ###############################################################################
14
+
15
+ import os
16
+ import re
17
+ from os import path as op
18
+ from . import PgLOG
19
+ from . import PgDBI
20
+ from . import PgUtil
21
+
22
+ #
23
+ # compare wfile records between tables wfile and wfile_dNNNNNN,
24
+ # and return the records need to be added, modified and deleted
25
+ #
26
+ def compare_wfile(wfrecs, dsrecs):
27
+
28
+ flds = dsrecs.keys()
29
+ flen = len(flds)
30
+ arecs = dict(zip(flds, [[]]*flen))
31
+ mrecs = {}
32
+ drecs = []
33
+ wfcnt = len(wfrecs['wid'])
34
+ dscnt = len(dsrecs['wid'])
35
+ pi = pj = -1
36
+ i = j = 0
37
+ while i < wfcnt and j < dscnt:
38
+ if i > pi:
39
+ wfrec = PgUtil.onerecord(wfrecs, i)
40
+ wwid = wfrec['wid']
41
+ pi = i
42
+ if j > pj:
43
+ dsrec = PgUtil.onerecord(dsrecs, j)
44
+ dwid = dsrec['wid']
45
+ pj = j
46
+ if wwid == dwid:
47
+ mrec = compare_one_record(flds, wfrec, dsrec)
48
+ if mrec: mrecs[wwid] = mrec
49
+ i += 1
50
+ j += 1
51
+ elif wwid > dwid:
52
+ drecs.append(dwid)
53
+ j += 1
54
+ else:
55
+ for fld in flds:
56
+ arecs[fld].append(wfrec[fld])
57
+ i += 1
58
+ if i < wfcnt:
59
+ for fld in flds:
60
+ arecs[fld].extend(wfrecs[fld][i:wfcnt])
61
+ elif j < dscnt:
62
+ drecs.extend(dsrecs['wid'][j:dscnt])
63
+
64
+ if len(arecs['wid']) == 0: arecs = {}
65
+
66
+ return (arecs, mrecs, drecs)
67
+
68
+ #
69
+ # Compare column values and return the new one; empty if the same
70
+ #
71
+ def compare_one_record(flds, wfrec, dsrec):
72
+
73
+ mrec = {}
74
+ for fld in flds:
75
+ if wfrec[fld] != dsrec[fld]: mrec[fld] = wfrec[fld]
76
+
77
+ return mrec
78
+
79
+ #
80
+ # convert wfile records to wfile_dsid records
81
+ #
82
+ def wfile2wdsid(wfrecs, wids = None):
83
+
84
+ dsrecs = {}
85
+ if wfrecs:
86
+ for fld in wfrecs:
87
+ if fld == 'dsid': continue
88
+ dsrecs[fld] = wfrecs[fld]
89
+ if wids: dsrecs['wid'] = wids
90
+ return dsrecs
91
+
92
+ #
93
+ # trim wfile records
94
+ #
95
+ def trim_wfile_fields(wfrecs):
96
+
97
+ records = {}
98
+ if 'wfile' in wfrecs: records['wfile'] = wfrecs['wfile']
99
+ if 'dsid' in wfrecs: records['dsid'] = wfrecs['dsid']
100
+
101
+ return records
102
+
103
+ #
104
+ # check the condition string, and add dsid if needed
105
+ #
106
+ def get_dsid_condition(dsid, condition):
107
+
108
+ if condition:
109
+ if re.search(r'(^|.| )(wid|dsid)\s*=', condition):
110
+ return condition
111
+ else:
112
+ dscnd = "wfile.dsid = '{}' ".format(dsid)
113
+ if not re.match(r'^\s*(ORDER|GROUP|HAVING|OFFSET|LIMIT)\s', condition, re.I): dscnd += 'AND '
114
+ return dscnd + condition # no where clause, append directly
115
+ else:
116
+ return "wfile.dsid = '{}'".format(dsid)
117
+
118
+ #
119
+ # insert one record into wfile and/or wfile_dsid
120
+ #
121
+ def pgadd_wfile(dsid, wfrec, logact = PgLOG.LOGERR, getid = None):
122
+
123
+
124
+ record = {'wfile' : wfrec['wfile'],
125
+ 'dsid' : (wfrec['dsid'] if 'dsid' in wfrec else dsid)}
126
+ wret = PgDBI.pgadd('wfile', record, logact, 'wid')
127
+ if wret:
128
+ record = wfile2wdsid(wfrec, wret)
129
+ PgDBI.pgadd('wfile_' + dsid, record, logact|PgLOG.ADDTBL)
130
+
131
+ if logact&PgLOG.AUTOID or getid:
132
+ return wret
133
+ else:
134
+ return 1 if wret else 0
135
+
136
+ #
137
+ # insert multiple records into wfile and/or wfile_dsid
138
+ #
139
+ def pgmadd_wfile(dsid, wfrecs, logact = PgLOG.LOGERR, getid = None):
140
+
141
+ records = {'wfile' : wfrecs['wfile'],
142
+ 'dsid' : (wfrecs['dsid'] if 'dsid' in wfrecs else [dsid]*len(wfrecs['wfile']))}
143
+ wret = PgDBI.pgmadd('wfile', records, logact, 'wid')
144
+ wcnt = wret if isinstance(wret, int) else len(wret)
145
+ if wcnt:
146
+ records = wfile2wdsid(wfrecs, wret)
147
+ PgDBI.pgmadd('wfile_' + dsid, records, logact|PgLOG.ADDTBL)
148
+
149
+ if logact&PgLOG.AUTOID or getid:
150
+ return wret
151
+ else:
152
+ return wcnt
153
+
154
+ #
155
+ # update one or multiple rows in wfile and/or wfile_dsid
156
+ # exclude dsid in condition
157
+ #
158
+ def pgupdt_wfile(dsid, wfrec, condition, logact = PgLOG.LOGERR):
159
+
160
+ record = trim_wfile_fields(wfrec)
161
+ if record:
162
+ wret = PgDBI.pgupdt('wfile', record, get_dsid_condition(dsid, condition), logact)
163
+ else:
164
+ wret = 1
165
+ if wret:
166
+ record = wfile2wdsid(wfrec)
167
+ if record: wret = PgDBI.pgupdt("wfile_" + dsid, record, condition, logact|PgLOG.ADDTBL)
168
+
169
+ return wret
170
+
171
+ #
172
+ # update one row in wfile and/or wfile_dsid with dsid change
173
+ # exclude dsid in condition
174
+ #
175
+ def pgupdt_wfile_dsid(dsid, odsid, wfrec, wid, logact = PgLOG.LOGERR):
176
+
177
+ record = trim_wfile_fields(wfrec)
178
+ cnd = 'wid = {}'.format(wid)
179
+ if record:
180
+ wret = PgDBI.pgupdt('wfile', record, cnd, logact)
181
+ else:
182
+ wret = 1
183
+ if wret:
184
+ record = wfile2wdsid(wfrec)
185
+ tname = 'wfile_' + dsid
186
+ doupdt = True
187
+ if odsid and odsid != dsid:
188
+ oname = 'wfile_' + odsid
189
+ pgrec = PgDBI.pgget(oname, '*', cnd, logact|PgLOG.ADDTBL)
190
+ if pgrec:
191
+ for fld in record:
192
+ pgrec[fld] = record[fld]
193
+ wret = PgDBI.pgadd(tname, pgrec, logact|PgLOG.ADDTBL)
194
+ if wret: PgDBI.pgdel(oname, cnd, logact)
195
+ doupdt = False
196
+ if doupdt and record:
197
+ wret = PgDBI.pgupdt(tname, record, cnd, logact|PgLOG.ADDTBL)
198
+
199
+ return wret
200
+
201
+ #
202
+ # delete one or multiple rows in wfile and/or wfile_dsid, and add the record(s) into wfile_delete
203
+ # exclude dsid in conidtion
204
+ #
205
+ def pgdel_wfile(dsid, condition, logact = PgLOG.LOGERR):
206
+
207
+ pgrecs = pgmget_wfile(dsid, '*', condition, logact|PgLOG.ADDTBL)
208
+ wret = PgDBI.pgdel('wfile', get_dsid_condition(dsid, condition), logact)
209
+ if wret: PgDBI.pgdel("wfile_" + dsid, condition, logact)
210
+ if wret and pgrecs: PgDBI.pgmadd('wfile_delete', pgrecs, logact)
211
+
212
+ return wret
213
+
214
+ #
215
+ # delete one or multiple rows in sfile, and add the record(s) into sfile_delete
216
+ #
217
+ def pgdel_sfile(condition, logact = PgLOG.LOGERR):
218
+
219
+ pgrecs = PgDBI.pgmget('sfile', '*', condition, logact)
220
+ sret = PgDBI.pgdel('sfile', condition, logact)
221
+ if sret and pgrecs: PgDBI.pgmadd('sfile_delete', pgrecs, logact)
222
+
223
+ return sret
224
+
225
+ #
226
+ # update one or multiple rows in wfile and/or wfile_dsid for multiple dsid
227
+ # exclude dsid in condition
228
+ #
229
+ def pgupdt_wfile_dsids(dsid, dsids, brec, bcnd, logact = PgLOG.LOGERR):
230
+
231
+ record = trim_wfile_fields(brec)
232
+ if record:
233
+ wret = PgDBI.pgupdt("wfile", record, bcnd, logact)
234
+ else:
235
+ wret = 1
236
+ if wret:
237
+ record = wfile2wdsid(brec)
238
+ if record:
239
+ wret = 0
240
+ dids = [dsid]
241
+ if dsids: dids.extend(dsids.split(','))
242
+ for did in dids:
243
+ wret += PgDBI.pgupdt("wfile_" + did, record, bcnd, logact|PgLOG.ADDTBL)
244
+
245
+ return wret
246
+
247
+ #
248
+ # get one record from wfile or wfile_dsid
249
+ # exclude dsid in fields and condition
250
+ #
251
+ def pgget_wfile(dsid, fields, condition, logact = PgLOG.LOGERR):
252
+
253
+ tname = "wfile_" + dsid
254
+ flds = fields.replace('wfile.', tname + '.')
255
+ cnd = condition.replace('wfile.', tname + '.')
256
+ record = PgDBI.pgget(tname, flds, cnd, logact|PgLOG.ADDTBL)
257
+ if record and flds == '*': record['dsid'] = dsid
258
+ return record
259
+
260
+ #
261
+ # get one record from wfile or wfile_dsid joing other tables
262
+ # exclude dsid in fields and condition
263
+ #
264
+ def pgget_wfile_join(dsid, tjoin, fields, condition, logact = PgLOG.LOGERR):
265
+
266
+ tname = "wfile_" + dsid
267
+ flds = fields.replace('wfile.', tname + '.')
268
+ jname = tname + ' ' + tjoin.replace('wfile.', tname + '.')
269
+ cnd = condition.replace('wfile.', tname + '.')
270
+ record = PgDBI.pgget(jname, flds, cnd, logact|PgLOG.ADDTBL)
271
+ if record and flds == '*': record['dsid'] = dsid
272
+ return record
273
+
274
+ #
275
+ # get multiple records from wfile or wfile_dsid
276
+ # exclude dsid in fields and condition
277
+ #
278
+ def pgmget_wfile(dsid, fields, condition, logact = PgLOG.LOGERR):
279
+
280
+ tname = "wfile_" + dsid
281
+ flds = fields.replace('wfile.', tname + '.')
282
+ cnd = condition.replace('wfile.', tname + '.')
283
+ records = PgDBI.pgmget(tname, flds, cnd, logact|PgLOG.ADDTBL)
284
+ if records and flds == '*': records['dsid'] = [dsid]*len(records['wid'])
285
+ return records
286
+
287
+ #
288
+ # get multiple records from wfile or wfile_dsid joining other tables
289
+ # exclude dsid in fields and condition
290
+ #
291
+ def pgmget_wfile_join(dsid, tjoin, fields, condition, logact = PgLOG.LOGERR):
292
+
293
+ tname = "wfile_" + dsid
294
+ flds = fields.replace('wfile.', tname + '.')
295
+ jname = tname + ' ' + tjoin.replace('wfile.', tname + '.')
296
+ cnd = condition.replace('wfile.', tname + '.')
297
+ records = PgDBI.pgmget(jname, flds, cnd, logact|PgLOG.ADDTBL)
298
+ if records and flds == '*': records['dsid'] = [dsid]*len(records['wid'])
299
+ return records