Skip to content

Commit

Permalink
allow to load the same alias multiple times (unless dbRecordsOnceOnly…
Browse files Browse the repository at this point in the history
… is set)
  • Loading branch information
dirk-zimoch authored and mdavidsaver committed Dec 30, 2024
1 parent 9fb820b commit 72026a2
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 17 deletions.
7 changes: 7 additions & 0 deletions documentation/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ not propagate AMSG, either.
Channel Access links do not propagate AMSG, regardless of the MSS attribute,
because the message is not available over Channel Access.

### Allow to load the same alias multiple times

Aliases can now be defined multiple times as long as they still refer to the
same record, unless the shell variable dbRecordsOnceOnly is set.
This allows to load database files multiple times, even if they contain
alias definitions.

### DBE_PROPERTY event rate changed

Updating property fields now only post DBE_PROPERTY events if the
Expand Down
44 changes: 34 additions & 10 deletions modules/database/src/ioc/dbStatic/dbLexRoutines.c
Original file line number Diff line number Diff line change
Expand Up @@ -1263,24 +1263,50 @@ static void dbRecordInfo(char *name, char *value)
}
}

static long createAlias(DBENTRY *pdbentry, const char *alias)
{
DBENTRY tempEntry;
long status;
dbRecordNode *precnode = pdbentry->precnode;

if (precnode->aliasedRecnode) precnode = precnode->aliasedRecnode;
dbInitEntry(pdbentry->pdbbase, &tempEntry);
status = dbFindRecord(&tempEntry, alias);
if (status == 0) {
if (tempEntry.precnode->aliasedRecnode != precnode) {
if (tempEntry.precnode->aliasedRecnode)
fprintf(stderr, ERL_ERROR ": Alias \"%s\" for \"%s\": name already used by an alias for \"%s\"\n",
alias, dbGetRecordName(pdbentry),
tempEntry.precnode->aliasedRecnode->recordname);
else
fprintf(stderr, ERL_ERROR ": Alias \"%s\" for \"%s\": name already used by a record\n",
alias, dbGetRecordName(pdbentry));
status = S_dbLib_recExists;
} else if (dbRecordsOnceOnly) {
fprintf(stderr, ERL_ERROR ": Alias \"%s\" already defined and dbRecordsOnceOnly set.\n",
alias);
status = S_dbLib_recExists;
}
} else {
status = dbCreateAlias(pdbentry, alias);
}
dbFinishEntry(&tempEntry);
return status;
}

static void dbRecordAlias(char *name)
{
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;

if(dbRecordNameValidate(name))
return;

if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
status = dbCreateAlias(pdbentry, name);
if (status) {
fprintf(stderr, "Can't create alias \"%s\" for \"%s\"\n",
name, dbGetRecordName(pdbentry));

if (createAlias(pdbentry, name) != 0) {
yyerror(NULL);
return;
}
}

Expand All @@ -1298,9 +1324,7 @@ static void dbAlias(char *name, char *alias)
alias, name);
yyerror(NULL);
}
else if (dbCreateAlias(pdbEntry, alias)) {
fprintf(stderr, "Can't create alias \"%s\" referring to \"%s\"\n",
alias, name);
else if (createAlias(pdbEntry, alias) != 0) {
yyerror(NULL);
}
dbFinishEntry(pdbEntry);
Expand Down
6 changes: 6 additions & 0 deletions modules/database/test/ioc/db/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ dbTestIoc_DBD += xLink.dbd
dbTestIoc_DBD += devx.dbd
dbTestIoc_DBD += jlinkz.dbd
dbTestIoc_DBD += dbLinkdset.dbd
dbTestIoc_DBD += dbCore.dbd
TESTFILES += $(COMMON_DIR)/dbTestIoc.dbd ../xRecord.db

testHarness_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp
Expand Down Expand Up @@ -183,6 +184,11 @@ testHarness_SRCS += dbStaticTest.c
TESTFILES += ../dbStaticTest.db
TESTFILES += ../dbStaticTestAlias1.db
TESTFILES += ../dbStaticTestAlias2.db
TESTFILES += ../dbStaticTestAliasAgain1.db
TESTFILES += ../dbStaticTestAliasAgain2.db
TESTFILES += ../dbStaticTestAliasAgain3.db
TESTFILES += ../dbStaticTestAliasAgainError1.db
TESTFILES += ../dbStaticTestAliasAgainError2.db
TESTFILES += ../dbStaticTestRemove.db
TESTS += dbStaticTest

Expand Down
31 changes: 24 additions & 7 deletions modules/database/test/ioc/db/dbStaticTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <dbUnitTest.h>
#include <testMain.h>
#include <epicsString.h>
#include <iocsh.h>


static void testEntryRemoved(const char *pv)
Expand Down Expand Up @@ -321,16 +322,19 @@ static void testDbVerify(const char *record)
dbFinishEntry(&entry);
}

static void testWrongAliasRecord(const char *filename)
static void testReadDatabase(const char *filename, int expectToFail)
{
FILE *fp = NULL;
long status;
dbPath(pdbbase,"." OSI_PATH_LIST_SEPARATOR "..");
dbOpenFile(pdbbase, filename, &fp);
if(!fp) {
testAbort("Unable to read %s", filename);
testAbort("Unable to open %s", filename);
}
testOk(dbReadDatabaseFP(&pdbbase, fp, NULL, NULL) != 0,
"Wrong alias record in %s is expected to fail", filename);
status = dbReadDatabaseFP(&pdbbase, fp, NULL, NULL);
testOk(!status == !expectToFail,
"Reading %s%s", filename,
expectToFail ? " is expected to fail" : "");
}

void dbTestIoc_registerRecordDeviceDriver(struct dbBase *);
Expand All @@ -341,7 +345,7 @@ MAIN(dbStaticTest)
char *ldirDup;
FILE *fp = NULL;

testPlan(340);
testPlan(350);
testdbPrepare();

testdbReadDatabase("dbTestIoc.dbd", NULL, NULL);
Expand Down Expand Up @@ -370,8 +374,21 @@ MAIN(dbStaticTest)
}
free(ldirDup);

testWrongAliasRecord("dbStaticTestAlias1.db");
testWrongAliasRecord("dbStaticTestAlias2.db");
testReadDatabase("dbStaticTestAlias1.db", 1);
testReadDatabase("dbStaticTestAlias2.db", 1);

/* Test re-defining aliases */
testReadDatabase("dbStaticTestAliasAgain1.db", 0);
testReadDatabase("dbStaticTestAliasAgain1.db", 0);
testReadDatabase("dbStaticTestAliasAgain2.db", 0);
testReadDatabase("dbStaticTestAliasAgain2.db", 0);
testReadDatabase("dbStaticTestAliasAgain3.db", 0);
testReadDatabase("dbStaticTestAliasAgain3.db", 0);
testReadDatabase("dbStaticTestAliasAgainError1.db", 1);
testReadDatabase("dbStaticTestAliasAgainError2.db", 1);
iocshCmd("var dbRecordsOnceOnly 1");
testReadDatabase("dbStaticTestAliasAgain2.db", 1);
testReadDatabase("dbStaticTestAliasAgain3.db", 1);

testEntry("testrec.VAL");
testEntry("testalias.VAL");
Expand Down
4 changes: 4 additions & 0 deletions modules/database/test/ioc/db/dbStaticTestAliasAgain1.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Test re-load alias in record
record(x, "testrecAgain") {
alias("testaliasAgain1")
}
2 changes: 2 additions & 0 deletions modules/database/test/ioc/db/dbStaticTestAliasAgain2.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Test re-load alias for record
alias("testrecAgain", "testaliasAgain2")
2 changes: 2 additions & 0 deletions modules/database/test/ioc/db/dbStaticTestAliasAgain3.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Test re-load alias for alias
alias("testaliasAgain2", "testaliasAgain3")
2 changes: 2 additions & 0 deletions modules/database/test/ioc/db/dbStaticTestAliasAgainError1.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ERROR: alias using name of exising alias for different record
alias("testrec", "testaliasAgain1")
2 changes: 2 additions & 0 deletions modules/database/test/ioc/db/dbStaticTestAliasAgainError2.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ERROR: alias using name of exising record fails
alias("testrecAgain", "testrec")

0 comments on commit 72026a2

Please sign in to comment.