# How to build a C application that uses ISQL

Internet SQL (**ISQL**) is an embedded relational + storage-vector database
engine.  It runs **in-process** (no server, no network) inside your application
and stores data in a plain directory tree.  This guide shows how to call it from
a C program.

---

## 1. What's in this package (`NewIsqlHome\`)

```
NewIsqlHome\
  db\                 the database (the "home" you pass to the engine)
  bin\                isqldll.dll   +   isql_shell.exe (interactive CLI)
  lib\                isqldll.lib   (import lib for the DLL)
                      isqllib.lib   (static library, optional)
  include\
    h\                isql.h  isqlc.h  isqllib.h  +  supporting headers
    newpwd.c          password helper (only needed for the static library)
  examples\
    isql_example.c    all SQL commands, self-checking      (pure C)
    isql_shell.c      interactive shell source             (pure C)
    build_example.bat build the example (links the DLL)
    build_shell.bat   build the shell   (links the DLL)
  doc\
    HOWTO_BUILD_C_APP.md   (this file)
```

The database directory you pass to the engine is the **home**; the actual data
lives in `home\db`.  In this package the home is `NewIsqlHome` and the data is
in `NewIsqlHome\db`.

---

## 2. Prerequisites

* Windows, **x64 (64-bit)** build.
* **Visual Studio 2017** C/C++ build tools (toolset **v141**).  The build
  scripts call `vcvars64.bat`; edit the `VCVARS` line if your VS is elsewhere.
* Keep **`isqldll.dll` next to your `.exe`** (or on the `PATH`) at run time.

---

## 3. The C API in 20 lines

Include the umbrella header **`isql.h`** (it pulls in `isqlc.h` and the one
engine typedef it needs).  The whole API works with opaque 64-bit handles (KINT64 - use `KINT64`, not `long`, for handle variables on x64).

```c
#include "isql.h"

int main(void)
{
    KINT64 inst, start, obj;   /* handles are 64-bit (KINT64) */

    inst  = ISQL_CreateInternetSqlInstance();      /* create an instance   */
    ISQL_NoNetworkMode(inst);                      /* standalone, embedded */
    ISQL_DisableMessage(inst);                     /* no GUI popups        */
    start = ISQL_StartInternetSql(inst, "C:\\NewIsqlHome", "", "");  /* open */
    obj   = ISQL_NewObject(start);                 /* a statement handle   */

    ISQL_Exec(obj, "use default;");                /* select the database  */
    ISQL_SetOwnerAccess(obj);                      /* owner access (below) */

    ISQL_Exec(obj, "create table t(id number(5), name char(16));");
    ISQL_Exec(obj, "insert into t values(1,'hello');");

    ISQL_Exec(obj, "select * from t;");
    while (ISQL_Next(obj))                          /* iterate result rows  */
        printf("%s = %s\n", ISQL_Data(obj,"id"), ISQL_Data(obj,"name"));

    ISQL_FreeObject(obj);
    ISQL_StopInternetSql(start);
    return 0;
}
```

### Core entry points

| Function | Purpose |
|---|---|
| `long ISQL_CreateInternetSqlInstance(void)` | create an engine instance |
| `void ISQL_NoNetworkMode(long inst)` | run standalone (no server/network) |
| `void ISQL_DisableMessage(long inst)` | suppress GUI message boxes |
| `long ISQL_StartInternetSql(long inst, char* home, char* ip, char* port)` | open the database under `home\db` (ip/port empty for local) |
| `long ISQL_NewObject(long startid)` | create a statement/cursor object |
| `long ISQL_SetOwnerAccess(long obj)` | grant embedded owner access (see §5) |
| `long ISQL_Exec(long obj, char* sql)` | run one SQL statement |
| `long ISQL_Next(long obj)` | advance the result cursor (0 = no more rows) |
| `char* ISQL_Data(long obj, char* field)` | current row's field value, by name |
| `int   ISQL_FieldCount(long obj)` | number of result columns |
| `char* ISQL_FieldName(long obj, long n)` | column name (1-based) |
| `char* ISQL_DataByFno(long obj, long n)` | current row's value by column number |
| `char* ISQL_Status(long obj)` | human-readable status of the last statement |
| `void  ISQL_FreeObject(long obj)` | free a statement object |
| `void  ISQL_StopInternetSql(long startid)` | close the database |

---

## 4. Building

### Against the DLL (recommended)

```
examples\build_example.bat      REM builds examples\isql_example.exe
examples\build_shell.bat        REM builds bin\isql_shell.exe
```

The essential compile/link (x64, static CRT so the .exe is self-contained):

```
cl /nologo /MT /W3 /O2 /D WIN32 /D _CRT_SECURE_NO_WARNINGS ^
   /I"NewIsqlHome\include\h" ^
   myapp.c  "NewIsqlHome\lib\isqldll.lib" ^
   /Fe"myapp.exe"
```

Then copy `isqldll.dll` next to `myapp.exe`.

### Against the static library (no DLL)

Link `lib\isqllib.lib` and compile `include\newpwd.c` alongside your app.  The
static library exposes the same `ISQL_*` C API **except** it must be built with
the matching CRT (`/MTd /D _DEBUG` for the shipped `isqllib.lib`).  Prefer the
DLL unless you specifically need a single static binary.

---

## 5. Access model: owner vs. login

ISQL supports multi-user accounts, but the common embedded case is: **your
application owns the database**, so it opens it with full rights.

* **`ISQL_SetOwnerAccess(obj)`** — call once after `ISQL_NewObject` (and a
  `use <db>;`) to get owner (superuser) access to the local database.  This is
  what the example and shell use.

* **Multi-user login** — the SQL account commands are available:

  ```sql
  add user analyst,secret123,a;     -- a=administrator, m=manager, o=ordinary
  login analyst,secret123;          -- password must be >= 6 chars
  ```

  For **this SDK drop, use `ISQL_SetOwnerAccess` as the working access path** (it
  is what the example and shell use and is fully exercised).  The multi-user
  `login` flow is present but still being finalized and will be validated
  end-to-end in a later update.

---

## 6. SQL commands (quick reference)

Run `help;` in the shell (`bin\isql_shell.exe`) for the live list.  Summary:

```
use <db>;
create table <t>(<col> <type>[, ...]);     types: number(n)  char(n)  storage
drop table <t>;                            describe <t>;
create index <ix> on <t>(<col>);           drop index <ix> on <t>;
insert into <t> values(<v>[, ...]);
select <cols|*> from <t> [where <cond>] [order by <col>];
update <t> set <col>=<v> [where <cond>];
delete from <t> [where <cond>];
   where: = <> < > <= >= , like 'p%' , and/or ;  aggregates: count sum avg min max
vinsert <vcol> into <t> values '<f,f,...>' [, <col>=<v> ...];   -- storage vectors
vector  <vcol> from <t> where query='<f,f,...>' and maxdistance=<d>;
add user <n>,<pwd>,<a|m|o>;   drop user <n>;   login <n>,<pwd>;
```

Every one of these is demonstrated and self-checked in `examples\isql_example.c`.

---

## 7. Try it now

```
REM 1. build + run the self-checking example (expects "29 passed, 0 failed")
examples\build_example.bat
examples\isql_example.exe  C:\NewIsqlHome

REM 2. play in the interactive shell
examples\build_shell.bat
bin\isql_shell.exe  C:\NewIsqlHome
isql> help;
isql> select * from employees;
isql> quit;
```

---

## 8. Notes & limits (this drop)

* x64 (64-bit) / v141 / Windows. The db ships EMPTY - the engine creates the
  64-bit catalog on first connection. A release-CRT static lib may follow.
* The engine is single-writer per process; for high concurrency run one process
  per connection (each process is fully isolated).
* This is a first SDK drop — the packaging (binaries, headers, examples) will be
  refreshed in future updates.
