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 명령
--mcpMCP 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;
TIP 필수·기본값 같은 제약은 속성이 아니라 타입의 속성 옵션으로 지정합니다. 같은 속성도 타입마다 다른 제약을 가질 수 있습니다.

스키마 ② 관계

SOURCETARGET으로 방향을 정의하고, 관계 자체가 속성을 가집니다.

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/NAVIGATEType: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';
작업구문결과
IterateUPDATE OBJECT Document:1 ITERATE;같은 리비전에서 이터레이션 +1
ReviseREVISE OBJECT Document:1 TO 'B' WITH FILE;새 리비전 생성, 이터레이션 초기화
CloneCLONE 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
처음이라면 빠른 시작부터 살펴보세요.