Skip to content

타입

MySQL 타입

SQLDelight 컬럼 정의는 일반적인 MySQL 컬럼 정의와 동일하지만, 생성된 인터페이스에서 컬럼의 Kotlin 타입을 지정하는 추가 컬럼 제약 사항(extra column constraint)을 지원합니다.

sql
CREATE TABLE some_types (
  some_bit BIT,                      -- Boolean으로 가져옴
  some_tiny_int TINYINT,             -- Byte로 가져옴 
  some_small_int SMALLINT,           -- Short으로 가져옴
  some_medium_int MEDIUMINT,         -- Int로 가져옴
  some_integer INTEGER,              -- Int로 가져옴
  some_int INT,                      -- Int로 가져옴
  some_big_int BIGINT,               -- Long으로 가져옴
  some_decimal DECIMAL,              -- Double로 가져옴
  some_dec DEC,                      -- Double로 가져옴
  some_fixed FIXED,                  -- Double로 가져옴
  some_numeric NUMERIC,              -- BigDecimal로 가져옴
  some_float FLOAT,                  -- Double로 가져옴
  some_real REAL,                    -- Double로 가져옴
  some_double_prec DOUBLE PRECISION, -- Double로 가져옴
  some_double DOUBLE,                -- Double로 가져옴
  some_date DATE,                    -- LocalDate로 가져옴
  some_time TIME,                    -- LocalTime으로 가져옴
  some_datetime DATETIME,            -- LocalDateTime으로 가져옴
  some_timestamp TIMESTAMP,          -- OffsetDateTime으로 가져옴
  some_year YEAR,                    -- String으로 가져옴
  some_char CHAR,                    -- String으로 가져옴
  some_varchar VARCHAR(16),          -- String으로 가져옴
  some_tiny_text TINYTEXT,           -- String으로 가져옴
  some_text TEXT,                    -- String으로 가져옴
  some_medium_text MEDIUMTEXT,       -- String으로 가져옴
  some_long_text LONGTEXT,           -- String으로 가져옴
  some_enum ENUM,                    -- String으로 가져옴
  some_set SET,                      -- String으로 가져옴
  some_varbinary VARBINARY(8),       -- ByteArray로 가져옴
  some_blob BLOB(8, 8),              -- ByteArray로 가져옴
  some_binary BINARY,                -- ByteArray로 가져옴
  some_json JSON,                    -- String으로 가져옴
  some_boolean BOOLEAN,              -- Boolean으로 가져옴
);

커스텀 컬럼 타입

컬럼을 커스텀 타입으로 가져오고 싶다면 Kotlin 타입을 지정할 수 있습니다:

sql
import kotlin.String;
import kotlin.collections.List;

CREATE TABLE hockeyPlayer (
  cup_wins TEXT AS List<String> NOT NULL
);

하지만 Database를 생성할 때 데이터베이스 타입과 커스텀 타입 간의 매핑 방법을 알고 있는 ColumnAdapter를 제공해야 합니다:

kotlin
val listOfStringsAdapter = object : ColumnAdapter<List<String>, String> {
  override fun decode(databaseValue: String) =
    if (databaseValue.isEmpty()) {
      listOf()
    } else {
      databaseValue.split(",")
    }
  override fun encode(value: List<String>) = value.joinToString(separator = ",")
}

val queryWrapper: Database = Database(
  driver = driver,
  hockeyPlayerAdapter = hockeyPlayer.Adapter(
    cup_winsAdapter = listOfStringsAdapter
  )
)

Enums

편의를 위해 SQLDelight 런타임에는 enum을 String 데이터로 저장하기 위한 ColumnAdapter가 포함되어 있습니다.

sql
import com.example.hockey.HockeyPlayer;

CREATE TABLE hockeyPlayer (
  position TEXT AS HockeyPlayer.Position
)
kotlin
val queryWrapper: Database = Database(
  driver = driver,
  hockeyPlayerAdapter = HockeyPlayer.Adapter(
    positionAdapter = EnumColumnAdapter()
  )
)

값 타입(Value types)

SQLDelight는 요청 시 기본 데이터베이스 타입을 래핑하는 컬럼용 값 타입(value type)을 생성할 수 있습니다:

sql
CREATE TABLE hockeyPlayer (
  id INT AS VALUE
);

## 낙관적 잠금 (Optimistic Locking)

컬럼을 `LOCK`으로 지정하면, 해당 컬럼에 대해 값 타입이 생성되며, `UPDATE` 문이 업데이트를 수행할 때 해당 잠금을 올바르게 사용해야 합니다.

```sql
CREATE TABLE hockeyPlayer(
  id INT AS VALUE,
  version_number INT AS LOCK,
  name VARCHAR(8)
);

-- 이 문장은 실패합니다 (IDE 플러그인이 아래와 같이 다시 작성할 것을 권장합니다)
updateName:
UPDATE hockeyPlayer
SET name = ?;

-- 이 문장은 컴파일에 성공합니다
updateNamePassing:
UPDATE hockeyPlayer
SET name = ?
    version_number = :version_number + 1
WHERE version_number = :version_number;

마이그레이션에서의 커스텀 타입 (Custom Types in Migrations)

마이그레이션이 스키마의 소스(source of truth)인 경우, 테이블을 변경(alter)할 때 노출될 Kotlin 타입을 지정할 수도 있습니다:

sql
import kotlin.String;
import kotlin.collection.List;

ALTER TABLE my_table
  ADD COLUMN new_column VARCHAR(8) AS List<String>;