|
Host/API | SIR/API |
The INIT
function initialise the system and defines two call back routines to handle
the output from the API. The first of these callbacks (writeLine) handles output which would normally go to the
main window, and the second (writeData) handles output from query type (LIST
) commands. The initialise function also
defines the start parameter string that you would normally use to start SIRDBMS or SIRSQL (eg: DB=COMPANY PW=COMPANY P=...
).
This initial function should be called first.
The EXEC
function executes a DBMS or SQL command or set of commands.
The STOP
function terminates the API, closing any open files and releasing handles. It should be called at the end of your program.
The other two functions return the VersionNumber
(this one can be called before INIT) and the ERROR
code. The latter can be called
after any API function that has a FALSE return code.
The system is not reenterable, so you must not call any of these functions before the previous call is completed. Also you cannot use both SirDBMS and SirSQL DLLs from the same application.
To compile your calls correctly under MS-Windows macro _WIN32
must
be defined. It is predefined by Visual C++. Define it in your make
file for other compilers. The macro will inforce __stdcall
calling
convention for the DLL's export names. You should use sirdbms.lib
or sirsql.lib import library to link your application.
To write a console application that does not have a windows interface then use a window handle (hWnd) of (void *) 1
.
SirDBMS_VersionNumber
int __StdCall SirDBMS_VersionNumber(void);Returns DBMS engine's version number (40000 for 4.00.00). It's the only function you can execute before
SirDBMS_Init()
.
SirDBMS_Init
int __StdCall SirDBMS_Init( void *hWnd, void (__StdCall *writeLine)(const char *text), void (__StdCall *writeData)(const char *text), const char *commandLine );Must be executed before sending commands to the DBMS engine.
The first argument is the system-specific handle of the main window. It should be the current window at this moment.
DBMS engine uses the function passed as the second argument to write a line of text into the message buffer. User interface module should immediately put the text into some output window.
DBMS engine uses the function passed as the third argument to write a line of text into the data buffer when given some query-type command.
The engine doesn't add any end-of-line terminators, it just makes one call for each line of output.
The last argument is a string which contains the command line arguments (without the leading application name).
Returns TRUE
on success, FALSE
on failure, doesn't return if
the command line activates the batch mode.
SirDBMS_Exec
int __StdCall SirDBMS_Exec(void *hWnd, const char *commands);Executes DBMS commands.
The first argument is the system-specific handle of the current window. It is used as the owner of the engine's message boxes.
The second argument is a DBMS command[s]. Multiple lines must be separated by '\n' character.
Returns TRUE on success, FALSE on failure.
SirDBMS_Stop
int __StdCall SirDBMS_Stop(void *hWnd);Call this before you terminate the program.
The argument is the system-specific handle of the current window. It is used as the owner of the engine's message boxes.
This will properly disconnect and close all open files.
Returns TRUE
on success, FALSE
on failure.
SirDBMS_ErrorCode
int __StdCall SirDBMS_ErrorCode(void);Call this to get the error code if one of the SirDBMS_... functions returned FALSE. Error code 0 means that information is not available.
LIST ATTRIBUTE LABELS
LIST ATTRIBUTE VALUES
LIST BUFFERLINE "buffername" [FROM start_line_number TO end_line_number]
LIST CONCTDTABFILES
LIST DBA
LIST DEFFAMILY
LIST DEFMEMBER
LIST EDITORNAME
LIST EDITORTYPE
LIST ERRORLIMIT
LIST FAMILIES
LIST GLOBAL LABELS
LIST GLOBAL VALUES
LIST INDEXDATA tabfile.table NAMES
LIST INDEXDATA tabfile.table TYPES
LIST INDICES tabfile.table
LIST LOADING
LIST MEMBERS
LIST MSGLIMIT
LIST MSGLVL
LIST OUTPUTFILE
LIST PAGELEN
LIST PAGEWID
LIST PRINTBACK CALL
LIST PRINTBACK COMMANDS
LIST PRINTBACK FORMAT
LIST PRINTBACK REMARK
LIST PRINTBACK REPEAT
LIST PRINTBACK USER
LIST PROCFILE
LIST RECORDS
LIST SORTN
LIST TABFILE [tabfile]
LIST TABLEDATA tabfile NAMES
LIST TABLEDATA tabfile TYPES
LIST TABLES
LIST TABLES tabfile
LIST WARNLIMIT
SirSQL_VersionNumber
int __StdCall SirSQL_VersionNumber(void);Returns SQL engine's version number (40000 for 4.00.00). It's the only function you can execute before
SirSQL_Init()
.
SirSQL_Init
int __StdCall SirSQL_Init( void *hWnd, void (__StdCall *writeLine)(const char *text), const char *commandLine );Must be executed before sending commands to the SQL engine.
The first argument is the system-specific handle of the main window. And it should be the current window at this moment.
SQL engine uses the function passed as the second argument to write a line of text into the output buffer. User interface module might immediately add the text into the output window or use results in some other way after it gets control back. The engine doesn't add any end-of-line terminators, it just makes one call for each line of output.
The last argument is a string which contains the command line arguments (without the leading application name).
Returns TRUE
on success, FALSE
on failure, doesn't return if
the command line activates the batch mode.
SirSQL_Exec
int __StdCall SirSQL_Exec(void *hWnd, const char *commands);Executes SQL commands.
The first argument is the system-specific handle of the current window. It is used as the owner of the engine's message boxes.
The second argument is a SQL command[s]. Multiple lines must be separated by '\n' character.
Returns TRUE
on success, FALSE
on failure.
SirSQL_Stop
int __StdCall SirSQL_Stop(void *hWnd);Call this before you terminate the program.
The argument is the system-specific handle of the current window. It is used as the owner of the engine's message boxes.
This will properly disconnect and close all open files.
Returns TRUE
on success, FALSE
on failure.
SirSQL_ErrorCode
int __StdCall SirSQL_ErrorCode(void);Call this to get the error code if one of the
SirSQL_...
functions returned FALSE
.
LIST
Commands
//********************************************************************** //* AcmeSQL - example of using SirAPI (see readme.txt) * //* * //* This software is provided as is, without any explicit or * //* implied warranties. Use it at your own risk. * //********************************************************************** #define STRICT #include <windows.h> #include <stdio.h> #ifndef _WIN32 #define _WIN32 #endif #include <sirapi.h> #include "acmesql.rh" const char *AppName = "AcmeSQL"; const char *IniFile = "acmesql.ini"; const int MinEngineVer = 41000; int InpWndRatio = 30; int AutoSave = FALSE; HINSTANCE hInst; HWND hFrame; HWND hInpWnd; HWND hOutWnd; HFONT hFont; char *GetInputText() { int length = GetWindowTextLength(hInpWnd); if (length == 0) return NULL; char *buffer = new char[length+1]; length = GetWindowText(hInpWnd, buffer, length+1); int Empty = TRUE; for (int i=0; i<length; i++) if (!isspace(buffer[i])) { Empty = FALSE; break; } if (Empty) { delete buffer; return NULL; } return buffer; } void SetInputText(const char *text) { SetWindowText(hInpWnd, text); } void SetOutputText(const char *text) { SetWindowText(hOutWnd, text); } void AddToOutputWindow(const char *text) { int length = GetWindowTextLength(hOutWnd); int addlen = strlen(text); char *tmp = new char[addlen+2+1]; memcpy(tmp, text, addlen); memcpy(tmp+addlen, "\r\n", 3); SendMessage(hOutWnd, EM_SETSEL, length, length); SendMessage(hOutWnd, EM_REPLACESEL, FALSE, (LPARAM)tmp); delete tmp; } void __StdCall OutputHandler(const char *text) { AddToOutputWindow(text); } int InitEngine(HWND hWnd, const char *CommandLine) { EnableWindow(hWnd, FALSE); int status = SirSQL_Init(hWnd, OutputHandler, CommandLine); if (status == FALSE) MessageBox( hWnd, "Cannot initialize the SQL engine", AppName, MB_OK | MB_ICONERROR); EnableWindow(hWnd, TRUE); return status; } int ShutdownEngine(HWND hWnd) { EnableWindow(hWnd, FALSE); int status = SirSQL_Stop(hWnd); if (status == FALSE) MessageBox( hWnd, "Cannot shutdown the SQL engine correctly", AppName, MB_OK | MB_ICONERROR); EnableWindow(hWnd, TRUE); return status; } int Execute(HWND hWnd, const char *command) { EnableWindow(hWnd, FALSE); SetCursor(LoadCursor(NULL, IDC_WAIT)); int status = SirSQL_Exec(hWnd, command); if (status == FALSE) Beep(500, 100); SetCursor(LoadCursor(NULL, IDC_ARROW)); EnableWindow(hWnd, TRUE); return status; } LRESULT MainWnd_OnCreate(HWND hWnd, char *CmdLine) { hFrame = hWnd; int dllVersion = SirSQL_VersionNumber(); if (dllVersion < MinEngineVer) { char buffer[1024]; sprintf( buffer, "Wrong dynamic link library\n\n" "The SQL engine from sirsql.dll version %d.%02d.%02d\n\n" "You must use SQL engine version %d.%02d.%02d or later", dllVersion/10000, dllVersion/100%100, dllVersion%100, MinEngineVer/10000, MinEngineVer/100%100, MinEngineVer%100); MessageBox(hWnd, buffer, AppName, MB_OK | MB_ICONERROR); return -1; } int fontSize = GetPrivateProfileInt(AppName, "FSize", 0, IniFile); HDC hDC = GetDC(hWnd); int fontHeight = -MulDiv(fontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72); ReleaseDC(hWnd, hDC); hFont = CreateFont( fontHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH, "Courier New"); if (hFont == NULL) hFont = CreateFont( 0, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH, "Courier New"); InpWndRatio = GetPrivateProfileInt(AppName, "InpWndRatio", 30, IniFile); if (InpWndRatio < 15 || InpWndRatio > 75) InpWndRatio = 30; hInpWnd = CreateWindowEx( 0, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN, 0, 0, 0, 0, hWnd, (HMENU)10030, hInst, NULL); if (hFont != NULL) SendMessage(hInpWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE,0)); SendMessage(hInpWnd, EM_LIMITTEXT, 0, 0); hOutWnd = CreateWindowEx( 0, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | ES_READONLY, 0, 0, 0, 0, hWnd, (HMENU)10031, hInst, NULL); if (hFont != NULL) SendMessage(hOutWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE,0)); SendMessage(hOutWnd, EM_LIMITTEXT, 0, 0); AutoSave = GetPrivateProfileInt(AppName, "AutoSave", FALSE, IniFile); if (!InitEngine(hWnd, CmdLine)) return -1; AddToOutputWindow(""); AddToOutputWindow("Welcome to AcmeSQL interface!"); AddToOutputWindow("This is a sample program for developers who plan to use SirAPI."); AddToOutputWindow("As a first step we advise you to read sirapi.h in api directory."); AddToOutputWindow("Should you wish to see some examples, the source code of AcmeSQL"); AddToOutputWindow("is in examples subdirectory. Have a look at readme.txt first."); AddToOutputWindow(""); return 0; } LRESULT MainWnd_OnClose(HWND hWnd) { if (AutoSave) Execute(hFrame, "SAVE"); ShutdownEngine(hWnd); DestroyWindow(hWnd); if (hFont != NULL) DeleteObject(hFont); return 0; } LRESULT MainWnd_OnSize(HWND , int w, int h) { int InpWndH = h*InpWndRatio/100; int OutWndH = h-InpWndH; MoveWindow(hOutWnd, 0, 0 , w, OutWndH, TRUE); MoveWindow(hInpWnd, 0, OutWndH, w, InpWndH, TRUE); return 0; } LRESULT MainWnd_OnSetFocus(HWND) { SetFocus(hInpWnd); return 0; } LRESULT MainWnd_OnCommand(HWND hWnd, WORD cmd, WORD NCode, HWND hControl) { switch (cmd) { case CMD_EXECUTE: { char *cmd = GetInputText(); if (cmd != NULL) { int len = strlen(cmd); int n = 0; for (int i = 0; i <= len; i++) { if (cmd[i] == '\r') { n++; } else { if (n != 0) { cmd[i-n] = cmd[i]; } } } if (Execute(hFrame, cmd)) SetInputText(""); SetFocus(hInpWnd); delete cmd; } break; } case CMD_EXIT: SendMessage(hWnd, WM_CLOSE, 0, 0); break; default: ; } if (NCode == EN_MAXTEXT || NCode == EN_ERRSPACE) { Beep(500, 100); if (hControl == hOutWnd) { SetOutputText(""); } } return 0; } LRESULT MainWnd_OnPaint(HWND hWnd) { HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); return 0; } LRESULT CALLBACK MainWnd_WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { typedef struct { short sz; void *p; } UNALIGNED *UP; switch (msg) { case WM_CREATE: return MainWnd_OnCreate( hWnd, (char *)((UP)(((LPCREATESTRUCT)lParam)->lpCreateParams))->p); case WM_CLOSE: return MainWnd_OnClose(hWnd); case WM_SIZE: return MainWnd_OnSize(hWnd, LOWORD(lParam), HIWORD(lParam)); case WM_SETFOCUS: return MainWnd_OnSetFocus(hWnd); case WM_COMMAND: return MainWnd_OnCommand( hWnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); case WM_PAINT: return MainWnd_OnPaint(hWnd); case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, msg, wParam, lParam); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int) { hInst = hInstance; WNDCLASS wc; wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; wc.lpfnWndProc = MainWnd_WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_MAINICON)); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); wc.lpszClassName = "MainWnd"; if (RegisterClass(&wc) == 0) return 0; struct { short sz; void *p; } CreateWindowParam = {sizeof(void *), lpCmdLine}; HWND hWnd = CreateWindowEx( WS_EX_APPWINDOW, wc.lpszClassName, AppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, &CreateWindowParam); if (hWnd == NULL) return 0; ShowWindow(hWnd, SW_SHOWDEFAULT); HACCEL hAccel = LoadAccelerators( hInstance, MAKEINTRESOURCE(IDR_ACCELTABLE)); MSG msg; while (GetMessage(&msg, 0, 0, 0) == TRUE) { if (!TranslateAccelerator(hWnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } DestroyIcon(wc.hIcon); return msg.wParam; }
DBMS>
prompt and run them by entering go
. Enter exit
to end the program. This
program was written by Dave Doulton of the University of Southampton.
#include <string.h> #include <stdio.h> #include "sirapi.h" void OutputHandler(const char *text) { if(text[0] == ' ') { printf("%s\n",text+1); } else { printf("%s\n",text); } } void DisplayHandler(const char *text) { if(text[0] == ' ') { printf("%s\n",text+1); } else { printf("%s\n",text); } } int main(int argc,char *argv[]) { int i; int res; char cmdLine[1024] = ""; char cmd[1024]= ""; char ocmd[1024]= ""; char line[200]=""; for (i = 1; i < argc; i++) { if (i > 1) strcat(cmdLine, " "); strcat(cmdLine, argv[i]); } res=SirDBMS_Init((void *) 1, (void *) OutputHandler, (void *) DisplayHandler, cmdLine); if (res != 1) { res=SirDBMS_ErrorCode(); printf("error code %ld\n",res); } printf("DBMS>"); while (gets(line) != NULL) { if(strcmp(line,"go") == 0) { res=SirDBMS_Exec((void *) 1,cmd); strcpy(ocmd,cmd); strcpy(cmd,""); printf("DBMS>"); } else { if(strcmp(line,"rep") ==0) { res=SirDBMS_Exec((void *) 1,ocmd); strcpy(cmd,""); printf("DBMS>"); } else { if(strcmp(line,"exit") ==0) { strcpy(cmd,""); break; } else { strcat(cmd,line); strcat(cmd,"\n"); printf("DBMS>"); } } } } res=SirDBMS_Exec((void *) 1,cmd); res=SirDBMS_Stop((void *) 1); return res; }
To run a SIRAPI application the SIR dynamic libraries (eg. sirdbms.dll sirmdr.dll etc) must be in the application's directory or PATH.