From f4ccf7bc8ca6800aa3568d0b9d1ce4f7086760f1 Mon Sep 17 00:00:00 2001 From: Irie Railton <175622981+irierr@users.noreply.github.com> Date: Tue, 10 Mar 2026 17:48:05 +0000 Subject: [PATCH] iocsh command dbCreateRecord (#812) * skeleton for implementation of dbCreateRecord iocsh exposure * Add functionality of dbCreateRecordCallFunc Includes adding dependancy to iocInit.h and a new error type in dbStaticLib.h * Fix error message for case when adding record to IOC post init * add new error message for when no record name is passed and check for empty strings * add release note for dbCreateRecord IOC shell command * fix issues from codeql in release notes * fix documentation md based on codacy styling --- documentation/new-notes/PR-812.md | 16 ++++++ .../src/ioc/dbStatic/dbStaticIocRegister.c | 50 +++++++++++++++++++ .../database/src/ioc/dbStatic/dbStaticLib.h | 30 +++++------ 3 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 documentation/new-notes/PR-812.md diff --git a/documentation/new-notes/PR-812.md b/documentation/new-notes/PR-812.md new file mode 100644 index 000000000..a15eabcca --- /dev/null +++ b/documentation/new-notes/PR-812.md @@ -0,0 +1,16 @@ +### Expose `dbCreateRecord` in IOC shell + +Add a new IOC shell command `dbCreateRecord` allowing for records to be created +from the shell. + +Only works when called before `iocInit` and will fail if called afterwards. + +The pdbbase variable, a record type, and the new record's name should be passed +as arguments. + +Example usage: + +```sh +dbCreateRecord(pdbbase, "ai", "example:ai") +iocInit() +``` diff --git a/modules/database/src/ioc/dbStatic/dbStaticIocRegister.c b/modules/database/src/ioc/dbStatic/dbStaticIocRegister.c index 26493f67a..c3dce5885 100644 --- a/modules/database/src/ioc/dbStatic/dbStaticIocRegister.c +++ b/modules/database/src/ioc/dbStatic/dbStaticIocRegister.c @@ -9,6 +9,7 @@ \*************************************************************************/ #include "iocsh.h" +#include "iocInit.h" #include "errSymTbl.h" #include "errlog.h" @@ -260,6 +261,54 @@ static void dbCreateAliasCallFunc(const iocshArgBuf *args) } } +static const iocshArg dbCreateRecordArg0 = { "recordType", iocshArgString}; +static const iocshArg dbCreateRecordArg1 = { "recordName", iocshArgString}; +static const iocshArg * const dbCreateRecordArgs[] = {&argPdbbase, &dbCreateRecordArg0, &dbCreateRecordArg1}; +static const iocshFuncDef dbCreateRecordFuncDef = { + "dbCreateRecord", + 3, + dbCreateRecordArgs, + "Add a new record to the database.\n" + "\n" + "Example: dbCreateRecord pdbbase ai record:name\n", +}; + +/** + * @brief Call function for dbCreateRecord iocsh command. + * Creates a new record in the database with the specified record type and record name. + * @param args The arguments passed from iocsh, where args[0] is the pointer to the database, + * args[1] is the record type name, and args[2] is the record name. + */ +static void dbCreateRecordCallFunc(const iocshArgBuf *args) +{ + DBENTRY ent; + long status; + enum iocStateEnum iocState; + + iocState = getIocState(); + if(iocState != iocVoid) { + status = S_dbLib_postInitRecRegister; + } + else { + dbInitEntry(*iocshPpdbbase, &ent); + if(!args[2].sval || (args[2].sval[0] == '\0')) { + status = S_dbLib_recordNameMissing; + } else if(!args[1].sval) { + status = S_dbLib_recordTypeNotFound; + } else { + status = dbFindRecordType(&ent, args[1].sval); + if(!status) { + status = dbCreateRecord(&ent, args[2].sval); + } + } + dbFinishEntry(&ent); + } + if(status) { + fprintf(stderr, ERL_ERROR ": %ld %s\n", status, errSymMsg(status)); + iocshSetError(1); + } +} + void dbStaticIocRegister(void) { iocshRegister(&dbDumpPathFuncDef, dbDumpPathCallFunc); @@ -278,4 +327,5 @@ void dbStaticIocRegister(void) iocshRegister(&dbPvdTableSizeFuncDef,dbPvdTableSizeCallFunc); iocshRegister(&dbReportDeviceConfigFuncDef, dbReportDeviceConfigCallFunc); iocshRegister(&dbCreateAliasFuncDef, dbCreateAliasCallFunc); + iocshRegister(&dbCreateRecordFuncDef, dbCreateRecordCallFunc); } diff --git a/modules/database/src/ioc/dbStatic/dbStaticLib.h b/modules/database/src/ioc/dbStatic/dbStaticLib.h index 6f772f27d..48f770dd5 100644 --- a/modules/database/src/ioc/dbStatic/dbStaticLib.h +++ b/modules/database/src/ioc/dbStatic/dbStaticLib.h @@ -252,20 +252,22 @@ DBCORE_API void dbCatString(char **string, int *stringLength, extern int dbStaticDebug; extern int dbConvertStrict; -#define S_dbLib_recordTypeNotFound (M_dbLib|1) /* Record Type does not exist */ -#define S_dbLib_recExists (M_dbLib|3) /* Record Already exists */ -#define S_dbLib_recNotFound (M_dbLib|5) /* Record Not Found */ -#define S_dbLib_flddesNotFound (M_dbLib|7) /* Field Description Not Found */ -#define S_dbLib_fieldNotFound (M_dbLib|9) /* Field Not Found */ -#define S_dbLib_badField (M_dbLib|11) /* Bad Field value */ -#define S_dbLib_menuNotFound (M_dbLib|13) /* Menu not found */ -#define S_dbLib_badLink (M_dbLib|15) /* Bad Link Field */ -#define S_dbLib_nameLength (M_dbLib|17) /* Record Name is too long */ -#define S_dbLib_noRecSup (M_dbLib|19) /* Record support not found */ -#define S_dbLib_strLen (M_dbLib|21) /* String is too long */ -#define S_dbLib_noSizeOffset (M_dbLib|23) /* Missing SizeOffset Routine - No record support? */ -#define S_dbLib_outMem (M_dbLib|27) /* Out of memory */ -#define S_dbLib_infoNotFound (M_dbLib|29) /* Info item Not Found */ +#define S_dbLib_recordTypeNotFound (M_dbLib|1) /* Record Type does not exist */ +#define S_dbLib_recExists (M_dbLib|3) /* Record Already exists */ +#define S_dbLib_recNotFound (M_dbLib|5) /* Record Not Found */ +#define S_dbLib_flddesNotFound (M_dbLib|7) /* Field Description Not Found */ +#define S_dbLib_fieldNotFound (M_dbLib|9) /* Field Not Found */ +#define S_dbLib_badField (M_dbLib|11) /* Bad Field value */ +#define S_dbLib_menuNotFound (M_dbLib|13) /* Menu not found */ +#define S_dbLib_badLink (M_dbLib|15) /* Bad Link Field */ +#define S_dbLib_nameLength (M_dbLib|17) /* Record Name is too long */ +#define S_dbLib_noRecSup (M_dbLib|19) /* Record support not found */ +#define S_dbLib_strLen (M_dbLib|21) /* String is too long */ +#define S_dbLib_noSizeOffset (M_dbLib|23) /* Missing SizeOffset Routine - No record support? */ +#define S_dbLib_outMem (M_dbLib|27) /* Out of memory */ +#define S_dbLib_infoNotFound (M_dbLib|29) /* Info item Not Found */ +#define S_dbLib_postInitRecRegister (M_dbLib|31) /* IOC already initialized - No new records can be added */ +#define S_dbLib_recordNameMissing (M_dbLib|33) /* Record name is required */ #ifdef __cplusplus }