Skip to content

Commit 2a3b04e

Browse files
FredAnsgerma89akaszynski
authored
Add checks before accessing database (#1119)
* Add Checks before accessing DB * Fix the messages format * Using a decorator to check the status of the DB * Adding unit tests * Added missing import * Fixing db object * extending checks Co-authored-by: German <[email protected]> Co-authored-by: Alex Kaszynski <[email protected]>
1 parent 1425624 commit 2a3b04e

File tree

5 files changed

+52
-5
lines changed

5 files changed

+52
-5
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""The mapdl database module, allowing the access to the MAPDL database from Python."""
22

3-
from .database import DBDef, MapdlDb # noqa: F401
3+
from .database import DBDef, MapdlDb, check_mapdl_db_is_alive # noqa: F401

src/ansys/mapdl/core/database/database.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Contains the MapdlDb classes, allowing the access to MAPDL DB from Python."""
22
from enum import Enum
3+
from functools import wraps
34
import os
45
import time
56
from warnings import warn
@@ -38,6 +39,32 @@ def __exit__(self, *args, **kwargs):
3839
self._mapdl._resume_routine()
3940

4041

42+
def check_mapdl_db_is_alive(function):
43+
"""
44+
Decorator to check that the MAPDL.DB has started.
45+
46+
It works for the DB object (DBDef) and for the derived object which has "_db" attribute.
47+
"""
48+
49+
@wraps(function)
50+
def wrapper(self, *args, **kwargs):
51+
if hasattr(self, "active"):
52+
active = self.active
53+
elif hasattr(self, "_db"):
54+
active = self._db.active
55+
else: # pragma: no cover
56+
raise Exception("The DB object could not be found.")
57+
58+
if not active:
59+
self._mapdl._log.error(
60+
f"Please start the MAPDL DB Server to access '{function.__name__}'."
61+
)
62+
return None
63+
return function(self, *args, **kwargs)
64+
65+
return wrapper
66+
67+
4168
class DBDef(Enum): # From MAPDL ansysdef.inc include file
4269

4370
"""Database type definitions."""
@@ -311,6 +338,7 @@ def clear(self, **kwargs):
311338
return self._mapdl.run("/CLEAR,ALL")
312339

313340
@property
341+
@check_mapdl_db_is_alive
314342
def nodes(self):
315343
"""
316344
MAPDL database nodes interface.
@@ -380,6 +408,7 @@ def nodes(self):
380408
return self._nodes
381409

382410
@property
411+
@check_mapdl_db_is_alive
383412
def elems(self):
384413
"""
385414
MAPDL database element interface.

src/ansys/mapdl/core/database/elems.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from ansys.api.mapdl.v0 import mapdl_db_pb2
1010

11-
from . import DBDef, MapdlDb
11+
from . import DBDef, MapdlDb, check_mapdl_db_is_alive
1212

1313

1414
class DbElems:
@@ -66,6 +66,7 @@ def __str__(self):
6666
lines.append(f" Maximum element number: {self.max_num}")
6767
return "\n".join(lines)
6868

69+
@check_mapdl_db_is_alive
6970
def first(self, ielm=0):
7071
"""
7172
Get the number of the first element.
@@ -99,6 +100,7 @@ def first(self, ielm=0):
99100
self._itelm = ielm
100101
return self.next()
101102

103+
@check_mapdl_db_is_alive
102104
def next(self):
103105
"""
104106
Return the number of the next selected element.
@@ -154,6 +156,7 @@ def next(self):
154156
# return self._itelm
155157
###########################################################################
156158

159+
@check_mapdl_db_is_alive
157160
def info(self, ielm, ikey):
158161
"""
159162
Get information about a element

src/ansys/mapdl/core/database/nodes.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from numpy.lib import recfunctions
1313

1414
from ..common_grpc import DEFAULT_CHUNKSIZE
15-
from .database import DBDef, MapdlDb
15+
from .database import DBDef, MapdlDb, check_mapdl_db_is_alive
1616

1717

1818
class DbNodes:
@@ -95,6 +95,7 @@ def _db(self):
9595
"""Return the weakly referenced instance of db."""
9696
return self._db_weakref()
9797

98+
@check_mapdl_db_is_alive
9899
def first(self, inod=0):
99100
"""
100101
Return the number of the first node.
@@ -127,6 +128,7 @@ def first(self, inod=0):
127128
self._itnod = inod
128129
return self.next()
129130

131+
@check_mapdl_db_is_alive
130132
def next(self):
131133
"""
132134
Return the number of the next selected node.
@@ -180,6 +182,7 @@ def next(self):
180182
# self._itnod = result.inum
181183
# return self._itnod
182184

185+
@check_mapdl_db_is_alive
183186
def info(self, inod, ikey):
184187
"""
185188
Return information about a node.
@@ -266,6 +269,7 @@ def info(self, inod, ikey):
266269
result = self._db._stub.NodInqr(request)
267270
return result.ret
268271

272+
@check_mapdl_db_is_alive
269273
def num(self, selected=False) -> int:
270274
"""
271275
Return the number of nodes, either selected or all.
@@ -295,6 +299,7 @@ def num(self, selected=False) -> int:
295299
return self.info(0, DBDef.DB_NUMDEFINED.value)
296300

297301
@property
302+
@check_mapdl_db_is_alive
298303
def max_num(self) -> int:
299304
"""
300305
Return the maximum node number.
@@ -310,6 +315,7 @@ def max_num(self) -> int:
310315
"""
311316
return self.info(0, DBDef.DB_MAXDEFINED.value)
312317

318+
@check_mapdl_db_is_alive
313319
def coord(self, inod):
314320
"""
315321
Return the location of a node.
@@ -345,6 +351,7 @@ def coord(self, inod):
345351
node = self._db._stub.getNod(request)
346352
return node.kerr, tuple(node.v)
347353

354+
@check_mapdl_db_is_alive
348355
def all_asarray(self):
349356
"""
350357
Return all node indices, coordinates, and angles as arrays.
@@ -442,6 +449,7 @@ def all_asarray(self):
442449

443450
return ind, coord, angle
444451

452+
@check_mapdl_db_is_alive
445453
def push(self, inod, x, y, z, xang=None, yang=None, zang=None):
446454
"""
447455
Push a single node into the DB.

tests/test_database.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
from ansys.mapdl.core.database import DBDef, MapdlDb
77
from ansys.mapdl.core.misc import random_string
88

9-
pytestmark = pytest.mark.skip
10-
119

1210
@pytest.fixture(scope="session")
1311
def db(mapdl):
@@ -215,3 +213,12 @@ def test__channel_str(db):
215213
assert ":" in db._channel_str
216214
assert re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", db._channel_str)
217215
assert re.search("\d{4,6}", db._channel_str)
216+
217+
218+
def test_off_db(mapdl, db):
219+
"""Testing that when there is no active database"""
220+
if db.active:
221+
db.stop()
222+
assert not mapdl.db.active
223+
assert mapdl.db.nodes is None
224+
assert mapdl.db.elems is None

0 commit comments

Comments
 (0)