def setnx(key, value, expires: nil)
      validate_key(key)
      validate_value(value)
      validate_expires(expires) if expires

      encapsulate_error {
        # if the key already exists but has expired, prune it first. We could
        # achieve the same thing with the right INSERT ... ON DUPLICATE KEY UPDATE
        # query, but then we would not be able to rely on affected_rows

        GitHub::SQL.run(<<-SQL, :key => key, :connection => connection)
          DELETE FROM key_values WHERE `key` = :key AND expires_at <= NOW()
        SQL

        sql = GitHub::SQL.run(<<-SQL, :key => key, :value => value, :expires => expires || GitHub::SQL::NULL, :connection => connection)
          INSERT IGNORE INTO key_values (`key`, value, created_at, updated_at, expires_at)
          VALUES (:key, :value, NOW(), NOW(), :expires)
        SQL

        sql.affected_rows > 0
      }
    end
def setnx(key, value, expires: nil)
      validate_key(key)
      validate_value(value)
      validate_expires(expires) if expires

      encapsulate_error {
        # if the key already exists but has expired, prune it first. We could
        # achieve the same thing with the right INSERT ... ON DUPLICATE KEY UPDATE
        # query, but then we would not be able to rely on affected_rows

        GitHub::SQL.run(<<-SQL, :key => key, :connection => connection)
          DELETE FROM key_values WHERE `key` = :key AND expires_at <= NOW()
        SQL

        sql = GitHub::SQL.run(<<-SQL, :key => key, :value => value, :expires => expires || GitHub::SQL::NULL, :connection => connection)
          INSERT IGNORE INTO key_values (`key`, value, created_at, updated_at, expires_at)
          VALUES (:key, :value, NOW(), NOW(), :expires)
        SQL

        sql.affected_rows > 0
      }
    end
setnx :: String, String, expires: Time? -> Boolean

 Sets the specified key to the specified value only if it does not
 already exist.

 Returns true if the key was set, false otherwise. Raises on error.

 Example:

   kv.setnx("foo", "bar")
     # => false

   kv.setnx("octocat", "monalisa")
     # => true

   kv.setnx("expires", "soon", expires: 1.hour.from_now)
     # => true