Reference
IQL이란
IQL(InterLink Query Language)은 업무 데이터를 그래프로 다루는 데이터베이스의 질의 언어입니다. 관계형 DB가 테이블·행·조인으로 데이터를 다룬다면, IQL은 객체·관계·타입·라이프사이클을 1급 시민으로 다룹니다. 데이터뿐 아니라 스키마·수명주기·권한 같은 메타 정의까지 그래프 안에서 IQL로 선언합니다.
- 객체(Object) — 업무 개체 하나. 타입과 시스템·사용자 속성을 가짐.
- 관계(Relationship) — 객체를 잇는 방향 간선. 자체 속성을 가지는 1급 객체.
- 타입(Type) — 객체/관계의 스키마. 상속(계층)을 지원.
- 라이프사이클(Lifecycle) — 상태 전이(Draft→Review→Released)와 리비전을 메타로 내장.
접속과 실행
Windows 런처는 콘솔·MCP 겸용 단일 실행 파일 iql.exe입니다(macOS/Linux는 동등 런처 iql).
# 콘솔 실행 후 데이터베이스 접속
iql.exe
CONNECT admin/able1234@dev;
FIND Person;
배치(스크립트) 모드
iql.exe -u admin -p password -t interlink -f scripts/daily.iql
iql.exe -u admin -p password -t interlink -c "FIND Person LIMIT 100;"
-u, --user | 사용자명 |
-p, --password | 비밀번호 |
-t, --tenant | 테넌트 이름 (database.yaml 의 키) |
-f, --file | 실행할 IQL 스크립트 파일 |
-c, --command | 직접 실행할 IQL 명령 |
--mcp | MCP stdio 서버 모드 |
속성 표기 규칙 — 시스템 vs 사용자 정의
IQL에서 가장 자주 헷갈리는 규칙입니다.
- 시스템 속성은 대괄호 없이:
id, type, name, title, description, version, revision, iteration, state, lifecycle, workspace, owner, createdon, createdby, modifiedon, modifiedby - 사용자 정의 속성은 대괄호로:
[email],[amount],[status]— 조회(WHERE·RETURN·ORDER BY)와 SET 절 모두에서. name은 시스템이 자동 부여 — 사용자에게 보여줄 이름은title.- 문자열은 작은따옴표
'…', 논리 우선순위는NOT > AND > OR.
-- 조회: 사용자 속성은 [ ]
FIND Person WHERE [age] > 30 RETURN name, [email], [age];
-- 생성/수정: 시스템 속성(title)은 [ ] 없이, 사용자 속성([email])은 [ ]
CREATE OBJECT Person LIFECYCLE Default SET title = 'John Doe', [email] = 'john@x.com';
데이터 타입
| 타입 | 설명 | 리터럴 예 |
|---|---|---|
string | 문자열 | 'text' |
longtext | 멀티라인 텍스트 | """여러 줄...""" |
integer | 정수 | 42 |
real | 실수 | 3.14 |
boolean | 불리언 | true, false |
datetime | 일시 | '2026-05-01T00:00:00', '2026-05-01' |
스키마 ① 속성과 타입
속성을 먼저 선언하고, 타입이 속성을 조합합니다. 제약은 타입 쪽에 붙습니다.
-- 속성 — 데이터의 부품
DEFINE PROPERTY code DATATYPE string;
DEFINE PROPERTY amount DATATYPE real;
DEFINE PROPERTY tags DATATYPE string MULTIVALUE true;
-- 타입 — 객체의 청사진 (제약은 타입에서)
DEFINE TYPE Order
DESCRIPTION '주문'
PROPERTY
orderNo REQUIRED true,
amount MIN 0,
qty DEFAULT 0,
priority [@Priority]; -- 열거형 참조
-- 상속과 추상
DEFINE TYPE BaseDoc ABSTRACT true PROPERTY title, content;
DEFINE TYPE Contract PARENT BaseDoc PROPERTY effectiveDate;
-- 운영 중 확장 / 조회
ALTER TYPE Order ADD PROPERTY tags;
LIST TYPE Order*; SHOW TYPE Order;
스키마 ② 관계
SOURCE와 TARGET으로 방향을 정의하고, 관계 자체가 속성을 가집니다.
DEFINE RELATIONSHIP OrderLine
SOURCE Order
TARGET Product
DUPLICATE false -- 같은 쌍 중복 링크 금지
PROPERTY qty, unitPrice; -- 관계 위의 데이터
-- 여러 타입 · 와일드카드
DEFINE RELATIONSHIP Contains SOURCE Department, Team TARGET Employee, Team;
DEFINE RELATIONSHIP Reference SOURCE * TARGET *; -- 모든 타입 허용
왜 관계 속성인가 — “주문에 담긴 상품 4개”에서 4는 상품의 속성이 아니라 주문·상품 사이의 사실입니다. 수량·유효기간·정렬 순서가 관계 속성으로 모델링됩니다. 개정 시 관계 처리는 FREEZE / FLOAT / REPLICATE / SHIFT 4모드로 지정합니다.
스키마 ③ 라이프사이클
상태 집합과 전이, 리비전 시퀀스, 상태별 역할 권한을 정의합니다.
DEFINE LIFECYCLE DocumentLC
FOR Document, Specification
REVISION SEQUENCE 'A,B,C,D' -- 대개정: Revise마다 진행
ITERATION SEQUENCE '1,2,3' -- 소변경: Iterate마다 진행
STATE
Draft
Viewer DENY READ, -- 상태 × 역할 권한
'In Review'
Viewer DENY UPDATE,
Released,
Obsolete;
-- 운영 중 상태 추가·권한 수정
ALTER LIFECYCLE DocumentLC ADD STATE Approved AFTER 'In Review';
- 공백이 있는 상태명만 따옴표(
'In Review'). - 권한은 상태별로
ALLOW/DENY— 화면이 아니라 엔진이 강제. REVISION SEQUENCE는 필수 절. 개정이 필요 없는 타입도'A'하나는 지정하세요.
조회 — GET · FIND
IQL의 조회 결과 절은 RETURN입니다.
-- GET: 한 개를 정확히
GET OBJECT Order:1 RETURN title, revision, [amount];
GET OBJECT Person(name = 'John Doe');
GET OBJECT Order:1 RETURN [*]; -- 모든 사용자 속성
GET OBJECT Order:1 RETURN FILES; -- 첨부 파일 목록
-- FIND: 조건으로 여럿을 (RETURN이 ORDER BY 앞)
FIND Order
WHERE [status] IN ('Active','Pending') AND [amount] BETWEEN 5 AND 30
RETURN id, title, [amount]
ORDER BY [amount] DESC LIMIT 50;
연산자: = != > >= < <= LIKE IN BETWEEN IS [NOT] NULL. 부모/추상 타입으로 FIND하면 자식 타입까지 함께 검색(폴리모픽). 전문 검색은 별도 명령 SEARCH.
AGGREGATE — 집계
AGGREGATE Person RETURN COUNT(*);
AGGREGATE Person WHERE [isActive] = true
BY [department]
RETURN COUNT(*) AS cnt, AVG([age]) AS avgAge;
AGGREGATE Person BY [department], [grade] RETURN COUNT(*); -- 다중 키
집계 함수: COUNT · SUM · AVG · MIN · MAX · MEDIAN · STDDEV · PERCENTILE. COUNT(*)는 AGGREGATE 전용입니다(FIND … RETURN COUNT(*) 불가).
조작 — CREATE · UPDATE · DELETE · LINK
-- 생성: LIFECYCLE 지정 필수
CREATE OBJECT Order LIFECYCLE OrderLC SET title = '3월 정기주문', [orderNo] = 'ORD-001';
-- 수정 / 일괄 수정 / unset(값 삭제)
UPDATE OBJECT Order:1 SET title = '3월 정기주문 v2', [amount] = 42.5;
UPDATE OBJECT Order WHERE [priority] = 'Low' SET [priority] = 'Medium';
UPDATE OBJECT Order:1 SET [memo] = null; -- 값 삭제
-- 삭제
DELETE OBJECT Order:1;
-- 관계 연결/해제 (관계 속성 포함)
LINK OrderLine Order:1 -> Product:2 SET [qty] = 4;
LINK WorksAt Employee(name='John') -> Department(name='Sales');
UNLINK OrderLine Order:1 -> Product:2;
UPDATE RELATIONSHIP relId SET [qty] = 10;
CREATE OBJECT에는LIFECYCLE필수. 타입명·LC명은 따옴표 없이.- 영숫자 id에
DELETE/NAVIGATE는Type:id대신 따옴표 id:DELETE OBJECT 'id';
SET 절의 함수·컨텍스트 값
-- 계산 대입 · 시퀀스 · 컨텍스트 함수
UPDATE OBJECT Employee(name='John') SET [code] = UPPER(TRIM([code]));
CREATE OBJECT Issue LIFECYCLE IssueLC SET title='Bug', [code] = IssueSeq.NEXTVAL;
CREATE OBJECT Issue LIFECYCLE IssueLC
SET [dueAt] = NOW(), [assignee] = USER(), [ws] = WORKSPACE();
수명주기 운용 — PROMOTE · 개정
PROMOTE Document:1; -- 다음 상태로
DEMOTE Document:1; -- 이전 상태로
PROMOTE OBJECT Document:1 TO 'Released'; -- 특정 상태로(순방향만)
-- WITH 체인: 한 문장 = 하나의 원자적 단위 (중간 실패 시 전체 롤백)
WITH OBJECT Document(code='DOC-001')
UPDATE SET description = '최종 승인'
THEN PROMOTE TO 'Released';
| 작업 | 구문 | 결과 |
|---|---|---|
| Iterate | UPDATE OBJECT Document:1 ITERATE; | 같은 리비전에서 이터레이션 +1 |
| Revise | REVISE OBJECT Document:1 TO 'B' WITH FILE; | 새 리비전 생성, 이터레이션 초기화 |
| Clone | CLONE OBJECT Document:1 WITH FILE; | 완전히 새로운 객체로 분기 |
스칼라·집계 함수
WHERE·RETURN·ORDER BY·AGGREGATE·SET 절에서 인라인 함수를 지원합니다.
-- 문자열
FIND Employee WHERE LOWER(title) LIKE LOWER('%kim%');
FIND Employee RETURN LEFT([code],3), SUBSTR([code],1,5), TRIM([code]), CONCAT([code],name);
-- 널 처리 · 분기 · 캐스트
FIND Employee RETURN COALESCE([team],'-'), CASE WHEN [grade]='A' THEN '우수' ELSE '일반' END, CAST([age] AS STRING);
-- 날짜 · 숫자
FIND Employee WHERE createdon >= DATE_ADD(TODAY(), -30, 'DAY');
AGGREGATE Employee BY DATE_TRUNC('month', createdon) RETURN COUNT(*);
AGGREGATE Employee RETURN ROUND(AVG([salary]), 1);
지원 함수: LOWER · UPPER · LEFT · SUBSTR · TRIM · CONCAT · COALESCE · CASE · CAST · DATE_ADD · DATE_TRUNC · EXTRACT · ROUND
시퀀스 (SEQUENCE)
CREATE SEQUENCE IssueNum START WITH 1 RESET YEARLY FORMAT 'ISS-YYYY-00000';
NEXTVAL SEQUENCE IssueNum; -- "ISS-2026-00001"
ALTER SEQUENCE IssueNum SET INCREMENT BY 2;
옵션: START WITH, INCREMENT BY, RESET NONE|YEARLY|MONTHLY, FORMAT(YYYY=연도, MM=월, 0000=제로패딩). SET 절에서 <Seq>.NEXTVAL로 인라인 주입 가능.
권한 (RBAC) — 엔진이 강제
테넌트(물리 격리) 안을 워크스페이스와 역할로 나눕니다. 권한은 질의 실행 시 강제되어 FIND·NAVIGATE·GET 결과를 자동 필터링합니다.
CREATE WORKSPACE 'Sales' VISIBILITY TEAM TYPE PROJECT;
GRANT WORKSPACE ROLE EDITOR ON WORKSPACE Sales TO USER john;
GRANT WORKSPACE ROLE VIEWER ON WORKSPACE Sales TO GROUP SalesTeam;
- 워크스페이스 가시성:
PUBLIC(전원) ·TEAM(역할 부여자) ·PRIVATE(OWNER, 기본값). - 역할 5종 고정: OWNER / MANAGER / EDITOR / VIEWER / GUEST. 여기에 라이프사이클 상태별 권한이 겹쳐집니다.
- 그룹에 부여하면 조직 개편 시 그룹 멤버십만 바꾸면 됩니다.
자동화 — 트리거 · iScript
이벤트 트리거와 서버사이드 스크립트로 검증·알림·연동·배치를 엔진 안에서 처리합니다. 결정적 로직과 (필요 시) LLM 판단을 함께 쓰는 자율 에이전트의 기반입니다.
트리거 — 이벤트에 반응하는 서버 로직
CREATE TRIGGER NotifyOnRelease
ON OBJECT Order -- OBJECT | RELATIONSHIP | LIFECYCLE
WHEN AFTER PROMOTE -- BEFORE|AFTER × CREATE/UPDATE/CHECKIN/PROMOTE…
ORDER 1
SCRIPT '''#!groovy
if (params.to_state == "Released") {
log.info("released: " + params.objectId)
}
''';
- BEFORE = 커밋 전 검증(throw로 차단) · AFTER = 커밋 후 알림·연동.
- 본문은 Groovy/Python — 첫 줄 셔뱅(
#!groovy/#!python)으로 선택. - 대상은
OBJECT · RELATIONSHIP · LIFECYCLE, 이벤트는CREATE/UPDATE/CHECKIN/PROMOTE등 ×BEFORE/AFTER.
iScript — 서버사이드 스크립트
-- 등록된 Groovy/Python 스크립트 실행
RUN ISCRIPT myBatch;
-- 스키마 변경 후 캐시 갱신
RELOAD CACHE;
스크립트 안에서는 iql.execute(...) 로 IQL을 실행하며 ?·:name 바인딩을 지원합니다. 일회성 백필·정기 배치도 서버에서 바로 수행할 수 있습니다.
통합 — Java · REST · MCP
사람·서버·AI가 같은 문장을 씁니다. 콘솔에서 검증한 질의를 그대로 코드·에이전트에 옮길 수 있습니다.
| 메서드 (IQLQueryService) | 용도 |
|---|---|
executeAsList(ctx, iql) | FIND/NAVIGATE → List<Map> |
executeAsMap(ctx, iql) | GET → Map |
executeAsJson(ctx, iql) | REST 응답용 JSON(에러도 JSON) |
run(ctx, iql) / runAll(…) | DML 실행(실패 시 예외) |
// 여러 문장의 원자성은 트랜잭션으로
context.withTx(() -> {
IQLQueryService.run(ctx, "LINK OrderLine 'a' -> 'b' SET [qty]=2;");
IQLQueryService.run(ctx, "PROMOTE OBJECT 'a';");
return null;
});
MCP 서버 — 엔진이 Model Context Protocol 서버를 내장(iql.exe --mcp)해, AI 에이전트가 IQL을 도구로 직접 호출합니다. 모델은 SHOW TYPE으로 스키마를 발견하고 자연어를 IQL로 변환하며, 권한은 질의 레벨에서 강제됩니다.
명령어 지도
| 영역 | 명령어 |
|---|---|
| 스키마 | DEFINE / ALTER / SHOW / LIST / DROP × TYPE · PROPERTY · RELATIONSHIP · LIFECYCLE · ENUMERATION |
| 데이터 | CREATE · GET · FIND · UPDATE · DELETE · LINK · UNLINK · NAVIGATE · AGGREGATE · SEARCH |
| 수명주기·파일 | PROMOTE · DEMOTE · REVISE · CLONE · UPDATE…ITERATE · CHECKIN · CHECKOUT · DOWNLOAD |
| 운영·권한 | CREATE USER/ROLE/GROUP · GRANT/REVOKE · CREATE WORKSPACE · CREATE VAULT · ALLOCATE |
| 자동화 | CREATE TRIGGER · CREATE SEQUENCE · NEXTVAL · RUN ISCRIPT · RELOAD CACHE |