Skip to content

Commit 4413e9b

Browse files
committed
added reader, writer stat method
1 parent 9d78d0c commit 4413e9b

File tree

13 files changed

+189
-5
lines changed

13 files changed

+189
-5
lines changed

src/h5json/h5pystore/h5py_reader.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import h5py
1313
import numpy as np
1414
import logging
15+
from os import stat as os_stat
1516
import time
1617

1718
from ..objid import createObjId, getCollectionForId
@@ -557,3 +558,16 @@ def getDatasetValues(self, dset_id, sel=None, dtype=None):
557558
# convert any h5py references to h5json references
558559
arr = self._copy_array(arr, fin=dset.file)
559560
return arr
561+
562+
def getStats(self):
563+
""" return a dictionary object with at minimum the following keys:
564+
'created': creation time
565+
'lastModified': modificationTime
566+
'owner': owner name
567+
"""
568+
stat_info = os_stat(self.filepath)
569+
stats = {}
570+
stats['created'] = stat_info.st_ctime
571+
stats["lastModified"] = stat_info.st_mtime
572+
stats['owner'] = stat_info.st_uid # TBD: convert to username?
573+
return stats

src/h5json/h5pystore/h5py_writer.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
##############################################################################
1212
import h5py
1313
import numpy as np
14+
from os import stat as os_stat
1415
import time
1516

1617
from ..objid import getCollectionForId, isValidUuid, createObjId
@@ -460,3 +461,16 @@ def close(self):
460461
def isClosed(self):
461462
""" return closed status """
462463
return False if self._f else True
464+
465+
def getStats(self):
466+
""" return a dictionary object with at minimum the following keys:
467+
'created': creation time
468+
'lastModified': modificationTime
469+
'owner': owner name
470+
"""
471+
stat_info = os_stat(self.filepath)
472+
stats = {}
473+
stats['created'] = stat_info.st_ctime
474+
stats["lastModified"] = stat_info.st_mtime
475+
stats['owner'] = stat_info.st_uid # TBD: convert to username?
476+
return stats

src/h5json/h5reader.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,12 @@ def close(self):
9292
def isClosed(self):
9393
""" return True if handle is closed """
9494
pass
95+
96+
@abstractmethod
97+
def getStats(self):
98+
""" return a dictionary object with at minimum the following keys:
99+
'created': creation time
100+
'lastModified': modificationTime
101+
'owner': owner name
102+
"""
103+
pass

src/h5json/h5writer.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(
3232
self._no_data = no_data
3333
self._filepath = filepath
3434
self._db_ref = None
35+
self._lastModified = None
3536
if app_logger:
3637
self.log = app_logger
3738
else:
@@ -49,6 +50,10 @@ def filepath(self):
4950
def closed(self):
5051
return self.isClosed()
5152

53+
@property
54+
def lastModified(self):
55+
return self._lastModified
56+
5257
@property
5358
def db(self):
5459
if not self._db_ref:
@@ -83,3 +88,12 @@ def close(self):
8388
def isClosed(self):
8489
""" return True if handle is closed """
8590
pass
91+
92+
@abstractmethod
93+
def getStats(self):
94+
""" return a dictionary object with at minimum the following keys:
95+
'created': creation time
96+
'lastModified': modificationTime
97+
'owner': owner name
98+
"""
99+
pass

src/h5json/hdf5db.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ def isClosed(self):
105105
""" return True if handle is closed """
106106
return self._is_closed
107107

108+
def getStats(self):
109+
""" return a dictionary object with at minimum the following keys:
110+
'created': creation time
111+
'lastModified': modificationTime
112+
'owner': owner name
113+
"""
114+
stats = {}
115+
stats['created'] = 0
116+
stats["lastModified"] = 0
117+
stats['owner'] = ""
118+
return stats
119+
108120

109121
class H5NullWriter(H5Writer):
110122
"""
@@ -165,6 +177,18 @@ def isClosed(self):
165177
""" return True if handle is closed """
166178
return self._is_closed
167179

180+
def getStats(self):
181+
""" return a dictionary object with at minimum the following keys:
182+
'created': creation time
183+
'lastModified': modificationTime
184+
'owner': owner name
185+
"""
186+
stats = {}
187+
stats['created'] = 0
188+
stats["lastModified"] = 0
189+
stats['owner'] = ""
190+
return stats
191+
168192

169193
class Hdf5db:
170194
"""
@@ -417,11 +441,11 @@ def _checkWriter(self):
417441
if self.writer.closed:
418442
raise IOError("writer is closed")
419443

420-
def getObjectById(self, obj_id):
444+
def getObjectById(self, obj_id, refresh=False):
421445
""" return object with given id """
422446
self.log.debug(f"getObjectById {obj_id}")
423447
self._checkReader()
424-
if obj_id not in self.db:
448+
if obj_id not in self.db or refresh:
425449
# load the obj from the reader
426450
obj_json = self.reader.getObjectById(obj_id)
427451
self.db[obj_id] = obj_json

src/h5json/hsdsstore/hsds_reader.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,15 @@ def getDatasetValues(self, dset_id, sel=None, dtype=None):
310310
self.log.debug(f"jsonToArray returned: {arr}")
311311

312312
return arr
313+
314+
def getStats(self):
315+
""" return a dictionary object with at minimum the following keys:
316+
'created': creation time
317+
'lastModified': modificationTime
318+
'owner': owner name
319+
"""
320+
stats = {}
321+
stats['created'] = 0
322+
stats["lastModified"] = 0
323+
stats['owner'] = ""
324+
return stats

src/h5json/hsdsstore/hsds_writer.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ def updateLinks(self, grp_ids):
385385
raise IOError("hsds_writer unable to update links")
386386
else:
387387
self.log.debug(f"hsds_writer> {grp_id} {count} links updated")
388+
self._lastModified = time.time()
388389

389390
def updateAttributes(self, obj_ids):
390391
""" update any modified links of the given objects """
@@ -418,6 +419,7 @@ def updateAttributes(self, obj_ids):
418419
self.log.error(f"hsds_writer> put {req} failed, status: {put_rsp.status_code}")
419420
else:
420421
self.log.debug(f"hsds_writer> {count} attributes updated")
422+
self._lastModified = time.time()
421423

422424
def updateValue(self, dset_id, sel, arr):
423425
""" update the given dataset using selection and array """
@@ -437,6 +439,7 @@ def updateValue(self, dset_id, sel, arr):
437439
self.log.error(f"PUT {req} returned error: {rsp.status_code}")
438440
else:
439441
self.log.debug(f"PUT {len(data)} bytes successful")
442+
self._lastModified = time.time()
440443

441444
def updateValues(self, dset_ids):
442445
""" write any pending dataset values """
@@ -476,7 +479,6 @@ def flush(self):
476479
if not self._http_conn:
477480
self.log.warning("hsds_writer no http connection")
478481
raise IOError("no http connection")
479-
480482
self.log.info("hsds_writer.flush()")
481483
self.log.debug(f" new object count: {len(self.db.new_objects)}")
482484
self.log.debug(f" dirty object count: {len(self.db.dirty_objects)}")
@@ -535,3 +537,15 @@ def isClosed(self):
535537
def get_root_id(self):
536538
""" Return root id """
537539
return self._root_id
540+
541+
def getStats(self):
542+
""" return a dictionary object with at minimum the following keys:
543+
'created': creation time
544+
'lastModified': modificationTime
545+
'owner': owner name
546+
"""
547+
stats = {}
548+
stats['created'] = 0
549+
stats["lastModified"] = 0
550+
stats['owner'] = ""
551+
return stats

src/h5json/jsonstore/h5json_reader.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
##############################################################################
1212
import json
1313
import logging
14+
from os import stat as os_stat
1415

1516
from ..objid import getCollectionForId, getUuidFromId
1617

@@ -215,3 +216,16 @@ def getDatasetValues(self, obj_id, sel=None, dtype=None):
215216
raise NotImplementedError("selection type not supported")
216217

217218
return arr
219+
220+
def getStats(self):
221+
""" return a dictionary object with at minimum the following keys:
222+
'created': creation time
223+
'lastModified': modificationTime
224+
'owner': owner name
225+
"""
226+
stat_info = os_stat(self.filepath)
227+
stats = {}
228+
stats['created'] = stat_info.st_ctime
229+
stats["lastModified"] = stat_info.st_mtime
230+
stats['owner'] = stat_info.st_uid # TBD: convert to username?
231+
return stats

src/h5json/jsonstore/h5json_writer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
##############################################################################
1212

1313
import json
14+
from os import stat as os_stat
15+
import time
1416

1517
from ..h5writer import H5Writer
1618
from ..objid import getUuidFromId, getCollectionForId, createObjId
@@ -292,3 +294,17 @@ def dumpFile(self):
292294
json.dump(self.json, f, ensure_ascii=ensure_ascii, indent=indent)
293295
else:
294296
print(json.dumps(self.json, sort_keys=True, ensure_ascii=ensure_ascii, indent=indent))
297+
self._lastModified = time.time() # update timestamp
298+
299+
def getStats(self):
300+
""" return a dictionary object with at minimum the following keys:
301+
'created': creation time
302+
'lastModified': modificationTime
303+
'owner': owner name
304+
"""
305+
stat_info = os_stat(self.filepath)
306+
stats = {}
307+
stats['created'] = stat_info.st_ctime
308+
stats["lastModified"] = stat_info.st_mtime
309+
stats['owner'] = stat_info.st_uid # TBD: convert to username?
310+
return stats

test/unit/h5json_writer_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ def testSimple(self):
7070
db.createSoftLink(g2_id, "slink", "somewhere")
7171
db.createExternalLink(g2_id, "extlink", "somewhere", "someplace")
7272
db.createCustomLink(g2_id, "cust", {"foo": "bar"})
73+
self.assertTrue(db.writer.lastModified is None) # no update yet
7374
db.flush()
75+
self.assertTrue(db.writer.lastModified > 0) # timestamp should be updated
7476

7577
def testNullSpaceAttribute(self):
7678

0 commit comments

Comments
 (0)