Kura
Early Access: Documentation is actively evolving and may change without notice.

Delete

Delete rows with the Lua builder.

local users = kura.db.tables.users

local changed = kura.db.delete(users)
  :where(op.eq(users.id, userId))
  :await()

String-based calls still work:

local changed = kura.db.delete('users')
  :where(op.eq('id', userId))
  :await()

Returning helpers

When you need deleted rows back, use the explicit helpers:

local users = kura.db.tables.users

local deletedRow = kura.db.delete(users)
  :where(op.eq(users.id, userId))
  :returningOne({ users.id, users.username })
  :await()

local deletedIds = kura.db.delete(users)
  :where(op.isNotNull(users.deletedAt))
  :returningRows({ users.id })
  :await()

Available helpers:

  • :returningRows({ ... })
  • :returningOne({ ... })
  • :returningValue(column)

Compatibility behavior

returning() is still supported, but plain await() on delete() remains compatibility-oriented:

local changed = kura.db.delete(users)
  :where(op.eq(users.id, userId))
  :returning({ users.id, users.username })
  :await()

returning() is compiled into SQL, but plain :await() on delete() still returns the affected row count for backwards compatibility. Use returningRows, returningOne, or returningValue when you want returned data.

Safety

delete() without where() is still allowed today and will delete every row in the target table. KuraDB does not yet enforce an allowAllRows()-style guard, so add where() explicitly unless a full-table delete is intentional.

Soft deletes

A common pattern is to use a nullable timestamp instead of actually deleting rows:

local users = kura.db.tables.users

kura.db.update(users)
  :set({ deletedAt = os.time() })
  :where(op.eq(users.id, userId))
  :await()

local active = kura.db.select()
  :from(users)
  :where(op.isNull(users.deletedAt))
  :await()

On this page