Skip to content

Commit 43a64c0

Browse files
author
d.kovalenko
committed
ConfigurationOsFile is added
1 parent d7139b9 commit 43a64c0

File tree

6 files changed

+219
-62
lines changed

6 files changed

+219
-62
lines changed

src/implementation/v00/configuration_base.py

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@
5858
from ...core.bugcheck_error import BugCheckError
5959
# fmt: on
6060

61+
from ...os.abstract.configuration_os_ops import ConfigurationFileReader
62+
from ...os.abstract.configuration_os_ops import ConfigurationOsFile
6163
from ...os.abstract.configuration_os_ops import ConfigurationOsOps
6264

6365
import typing
64-
import os
65-
import io
6666
import datetime
6767

6868
# //////////////////////////////////////////////////////////////////////////////
@@ -3223,17 +3223,14 @@ def LoadConfigurationFile(
32233223
# load content
32243224
# process content
32253225

3226-
with open(currentFileData.m_Path) as f:
3227-
assert isinstance(f, io.TextIOBase)
3226+
with cfg.m_Data.OsOps.OpenFileToRead(currentFileData.m_Path) as f:
3227+
assert isinstance(f, ConfigurationOsFile)
32283228
currentFile = PostgresConfigurationFactory_Base.GetObject(
32293229
cfg, currentFileData
32303230
)
32313231
__class__.Helper__LoadFileContent(currentFile, f) # raise
32323232

3233-
fd = f.fileno()
3234-
assert type(fd) == int
3235-
3236-
lastMDate = datetime.datetime.fromtimestamp(os.path.getmtime(fd))
3233+
lastMDate = f.GetModificationTS()
32373234
assert type(lastMDate) == datetime.datetime
32383235

32393236
currentFileData.m_LastModifiedTimestamp = lastMDate
@@ -3289,23 +3286,23 @@ def LoadConfigurationFile(
32893286

32903287
# --------------------------------------------------------------------
32913288
def LoadFileContent(
3292-
file: PostgresConfigurationFile_Base, fileContent: io.TextIOBase
3289+
file: PostgresConfigurationFile_Base, fileContent: ConfigurationFileReader
32933290
) -> None:
32943291
assert isinstance(file, PostgresConfigurationFile_Base)
3295-
assert isinstance(fileContent, io.TextIOBase)
3292+
assert isinstance(fileContent, ConfigurationFileReader)
32963293

32973294
return __class__.Helper__LoadFileContent(file, fileContent)
32983295

32993296
# Helper methods -----------------------------------------------------
33003297
def Helper__LoadFileContent(
3301-
file: PostgresConfigurationFile_Base, fileContent: io.TextIOBase
3298+
file: PostgresConfigurationFile_Base, fileContent: ConfigurationFileReader
33023299
) -> None:
33033300
assert isinstance(file, PostgresConfigurationFile_Base)
3304-
assert isinstance(fileContent, io.TextIOBase)
3301+
assert isinstance(fileContent, ConfigurationFileReader)
33053302

33063303
lineReader = ReadUtils__LineReader()
33073304

3308-
while lineData := fileContent.readline():
3305+
while lineData := fileContent.ReadLine():
33093306
assert type(lineData) == str
33103307

33113308
lineReader.SetData(lineData)
@@ -3727,7 +3724,7 @@ def Helper__ProcessLineData__Option__Generic(
37273724
class PostgresConfigurationWriterFileCtx_Base:
37283725
FileData: PgCfgModel__FileData
37293726
Content: typing.Optional[str]
3730-
File: typing.Optional[io.TextIOWrapper]
3727+
File: typing.Optional[ConfigurationOsFile]
37313728

37323729
# TODO: We can use filelock (it is a separated lock file)
37333730
# to provide an exclusive access to our File
@@ -3891,15 +3888,12 @@ def Helper__DoWork__Stage03__OpenUpdFilesToWrite(
38913888
assert fileCtx.File is None
38923889

38933890
# Let's open an exist file to read and write without truncation
3894-
fileCtx.File = open(fileCtx.FileData.m_Path, "r+") # raise
3891+
fileCtx.File = ctx.Cfg.m_Data.OsOps.OpenFileToWrite(fileCtx.FileData.m_Path) # raise
38953892

38963893
assert fileCtx.File is not None
3897-
assert isinstance(fileCtx.File, io.TextIOWrapper)
3898-
3899-
fd = fileCtx.File.fileno()
3900-
assert type(fd) == int
3894+
assert isinstance(fileCtx.File, ConfigurationOsFile)
39013895

3902-
lastMDate = datetime.datetime.fromtimestamp(os.path.getmtime(fd))
3896+
lastMDate = fileCtx.File.GetModificationTS()
39033897
assert type(lastMDate) == datetime.datetime
39043898

39053899
if fileCtx.FileData.m_LastModifiedTimestamp != lastMDate:
@@ -3937,10 +3931,10 @@ def Helper__DoWork__Stage04__OpenNewFilesToWrite(
39373931
assert fileCtx.FileData.m_Status == PgCfgModel__FileStatus.IS_NEW
39383932
assert fileCtx.File is None
39393933

3940-
fileCtx.File = open(fileCtx.FileData.m_Path, "x") # raise
3934+
fileCtx.File = ctx.Cfg.m_Data.OsOps.CreateFile(fileCtx.FileData.m_Path) # raise
39413935

39423936
assert fileCtx.File is not None
3943-
assert isinstance(fileCtx.File, io.TextIOWrapper)
3937+
assert isinstance(fileCtx.File, ConfigurationOsFile)
39443938

39453939
# OK
39463940
continue
@@ -3959,16 +3953,16 @@ def Helper__DoWork__Stage04__OpenNewFilesToWrite(
39593953

39603954
assert fileCtx.FileData.m_Status == PgCfgModel__FileStatus.IS_NEW
39613955
assert fileCtx.File is not None
3962-
assert isinstance(fileCtx.File, io.TextIOWrapper)
3956+
assert isinstance(fileCtx.File, ConfigurationOsFile)
39633957

3964-
assert not fileCtx.File.closed
3958+
assert not fileCtx.File.IsClosed
39653959

3966-
filePath = fileCtx.File.name
3960+
filePath = fileCtx.File.Name
39673961
assert filePath is not None
39683962
assert type(filePath) == str
39693963
assert filePath == fileCtx.FileData.m_Path
39703964

3971-
fileCtx.File.close() # raise
3965+
fileCtx.File.Close() # raise
39723966

39733967
ctx.Cfg.m_Data.OsOps.Remove(filePath) # raise
39743968
continue
@@ -3992,22 +3986,17 @@ def Helper__DoWork__Stage05__WriteContents(
39923986
assert type(fileCtx.FileData) == PgCfgModel__FileData
39933987

39943988
assert fileCtx.File is not None
3995-
assert isinstance(fileCtx.File, io.TextIOWrapper)
3989+
assert isinstance(fileCtx.File, ConfigurationOsFile)
39963990

39973991
assert fileCtx.Content is not None
39983992
assert type(fileCtx.Content) == str
39993993

4000-
fileCtx.File.write(fileCtx.Content)
4001-
fileCtx.File.truncate()
4002-
fileCtx.File.flush()
4003-
4004-
fd = fileCtx.File.fileno()
4005-
assert type(fd) == int
3994+
fileCtx.File.Overwrite(fileCtx.Content)
40063995

4007-
lastMDate = datetime.datetime.fromtimestamp(os.path.getmtime(fd))
3996+
lastMDate = fileCtx.File.GetModificationTS()
40083997
assert type(lastMDate) == datetime.datetime
40093998

4010-
fileCtx.File.close()
3999+
fileCtx.File.Close()
40114000

40124001
fileCtx.FileData.m_LastModifiedTimestamp = lastMDate
40134002
fileCtx.FileData.m_Status = PgCfgModel__FileStatus.EXISTS

src/os/abstract/configuration_os_ops.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,45 @@
55

66
from ...core.raise_error import RaiseError
77

8+
import datetime
9+
10+
11+
# //////////////////////////////////////////////////////////////////////////////
12+
# class ConfigurationFileReader
13+
14+
15+
class ConfigurationFileReader:
16+
def ReadLine(self) -> str:
17+
RaiseError.MethodIsNotImplemented(__class__, "ReadLine")
18+
19+
20+
# //////////////////////////////////////////////////////////////////////////////
21+
# class ConfigurationOsFile
22+
23+
24+
class ConfigurationOsFile(ConfigurationFileReader):
25+
def __init__(self):
26+
pass
27+
28+
@property
29+
def Name(self) -> str:
30+
RaiseError.MethodIsNotImplemented(__class__, "get_Name")
31+
32+
@property
33+
def IsClosed(self) -> bool:
34+
RaiseError.MethodIsNotImplemented(__class__, "get_IsClosed")
35+
36+
def Overwrite(self, text: str) -> None:
37+
assert type(text) == str # noqa: E721
38+
RaiseError.MethodIsNotImplemented(__class__, "Write")
39+
40+
def Close(self):
41+
RaiseError.MethodIsNotImplemented(__class__, "Close")
42+
43+
def GetModificationTS(self) -> datetime.datetime:
44+
RaiseError.MethodIsNotImplemented(__class__, "GetModificationTS")
45+
46+
847
# //////////////////////////////////////////////////////////////////////////////
948
# class ConfigurationOsOps
1049

@@ -43,5 +82,16 @@ def Remove(self, a: str) -> str:
4382
assert type(a) == str # noqa: E721
4483
RaiseError.MethodIsNotImplemented(__class__, "Remove")
4584

85+
def OpenFileToRead(self, filePath: str) -> ConfigurationOsFile:
86+
assert type(filePath) == str # noqa: E721
87+
RaiseError.MethodIsNotImplemented(__class__, "OpenFileToRead")
88+
89+
def OpenFileToWrite(self, filePath: str) -> ConfigurationOsFile:
90+
assert type(filePath) == str # noqa: E721
91+
RaiseError.MethodIsNotImplemented(__class__, "OpenFileToWrite")
92+
93+
def CreateFile(self, filePath: str) -> ConfigurationOsFile:
94+
assert type(filePath) == str # noqa: E721
95+
RaiseError.MethodIsNotImplemented(__class__, "CreateFile")
4696

4797
# //////////////////////////////////////////////////////////////////////////////

src/os/local/configuration_os_ops.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,82 @@
66
from ..abstract import configuration_os_ops as abstract
77

88
import os
9+
import io
10+
import datetime
11+
12+
# //////////////////////////////////////////////////////////////////////////////
13+
# class ConfigurationOsFile
14+
15+
16+
class ConfigurationOsFile(abstract.ConfigurationOsFile):
17+
m_file: io.TextIOWrapper
18+
19+
# --------------------------------------------------------------------
20+
def __init__(self, file: io.TextIOWrapper):
21+
assert isinstance(file, io.TextIOWrapper)
22+
23+
super().__init__()
24+
25+
self.m_file = file
26+
27+
# --------------------------------------------------------------------
28+
def __enter__(self) -> ConfigurationOsFile:
29+
assert isinstance(self.m_file, io.TextIOWrapper)
30+
return self
31+
32+
# --------------------------------------------------------------------
33+
def __exit__(self, exc_type, exc_val, exc_tb):
34+
if self.m_file is not None:
35+
self.Close()
36+
37+
assert self.m_file is None
38+
return
39+
40+
# --------------------------------------------------------------------
41+
@property
42+
def Name(self) -> str:
43+
assert isinstance(self.m_file, io.TextIOWrapper)
44+
return self.m_file.name
45+
46+
# --------------------------------------------------------------------
47+
@property
48+
def IsClosed(self) -> bool:
49+
return self.m_file is None
50+
51+
# --------------------------------------------------------------------
52+
def ReadLine(self) -> str:
53+
assert isinstance(self.m_file, io.TextIOWrapper)
54+
return self.m_file.readline()
55+
56+
# --------------------------------------------------------------------
57+
def Overwrite(self, text: str) -> None:
58+
assert type(text) == str # noqa: E721
59+
assert isinstance(self.m_file, io.TextIOWrapper)
60+
self.m_file.seek(0)
61+
self.m_file.write(text)
62+
self.m_file.truncate()
63+
self.m_file.flush()
64+
65+
# --------------------------------------------------------------------
66+
def Close(self):
67+
assert isinstance(self.m_file, io.TextIOWrapper)
68+
f = self.m_file
69+
self.m_file = None
70+
f.close()
71+
# Returning False (or None) re-raises the exception
72+
return False
73+
74+
# --------------------------------------------------------------------
75+
def GetModificationTS(self) -> datetime.datetime:
76+
assert isinstance(self.m_file, io.TextIOWrapper)
77+
78+
fd = self.m_file.fileno()
79+
assert type(fd) == int # noqa: E721
80+
81+
lastMDate = datetime.datetime.fromtimestamp(os.path.getmtime(fd))
82+
assert type(lastMDate) == datetime.datetime # noqa: E721
83+
return lastMDate
84+
985

1086
# //////////////////////////////////////////////////////////////////////////////
1187
# class ConfigurationOsOps
@@ -45,6 +121,21 @@ def Remove(self, a: str) -> str:
45121
assert type(a) == str # noqa: E721
46122
os.remove(a)
47123

124+
def OpenFileToRead(self, filePath: str) -> ConfigurationOsFile:
125+
assert type(filePath) == str # noqa: E721
126+
f = open(filePath)
127+
return ConfigurationOsFile(f)
128+
129+
def OpenFileToWrite(self, filePath: str) -> ConfigurationOsFile:
130+
assert type(filePath) == str # noqa: E721
131+
f = open(filePath, mode="r+")
132+
return ConfigurationOsFile(f)
133+
134+
def CreateFile(self, filePath: str) -> ConfigurationOsFile:
135+
assert type(filePath) == str # noqa: E721
136+
f = open(filePath, mode="x")
137+
return ConfigurationOsFile(f)
138+
48139

49140
# //////////////////////////////////////////////////////////////////////////////
50141

tests/CfgFileReader.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# /////////////////////////////////////////////////////////////////////////////
2+
# Postgres Pro. PostgreSQL Configuration Python Library. Tests.
3+
4+
from ..src.os.abstract.configuration_os_ops import ConfigurationFileReader
5+
6+
import io
7+
8+
# //////////////////////////////////////////////////////////////////////////////
9+
# class CfgFileReader
10+
11+
12+
class CfgFileReader(ConfigurationFileReader):
13+
m_file: io.StringIO
14+
15+
# --------------------------------------------------------------------
16+
def __init__(self, text: str):
17+
super().__init__()
18+
19+
self.m_file = io.StringIO(text)
20+
21+
# --------------------------------------------------------------------
22+
def ReadLine(self) -> str:
23+
assert type(self.m_file) == io.StringIO
24+
return self.m_file.readline()
25+
26+
27+
# //////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)