var user_id = row[0].to_i
var token = new_token(user_id)
var u = new User(user_id, row[1].to_s)
+ stmt.close
return new LoginResult(u, token)
end
return null
# TODO update token timestamp and platform/client hint of last connection.
# These informations could help detect malicious access to the account.
- for row in stmt do return row[0].to_i
- return null
+ var res = null
+ for row in stmt do
+ res = row[0].to_i
+ break
+ end
+ return res
end
# Get `User` data from the integer `id`
var stmt = select("name FROM users WHERE ROWID = {id}")
assert stmt != null
- for row in stmt do return new User(id, row[0].to_s)
- return null
+ var res = null
+ for row in stmt do
+ res = new User(id, row[0].to_s)
+ break
+ end
+ return res
end
# Try to sign up a new user, return `true` on success
var b = beer_from_id(beer)
if b == null then return null
- for row in stmt do return new BeerStats(b, row[0].to_f, row[1].to_i)
- return null
+ var res = null
+ for row in stmt do
+ res = new BeerStats(b, row[0].to_f, row[1].to_i)
+ break
+ end
+ return res
end
# Fetch the most recent rating left by `user_id` about `beer`
do
var stmt = select("rating FROM reviews WHERE author = {user_id} AND beer = {beer} ORDER BY ROWID DESC LIMIT 1")
assert stmt != null else print_error "Select 'rating' failed with: {error or else "?"}"
- for row in stmt do return row[0].to_i
- return null
+
+ var res = null
+ for row in stmt do
+ res = row[0].to_i
+ break
+ end
+ return res
end
# Register that `user_from` follows `user_to`
assert stmt != null else
print_error "Select 'follows' failed with: {error or else "?"}"
end
- for row in stmt do return true
+
+ for row in stmt.iterator.to_a do return true
return false
end
# List reciprocal friends of `user_id`
fun followed_followers(user_id: Int): nullable Array[User]
do
- var stmt = select("ROWID, name FROM users WHERE " +
- "ROWID in (SELECT user_from FROM follows WHERE user_to = {user_id}) AND " +
- "ROWID in (SELECT user_to FROM follows WHERE user_from = {user_id})")
+ var stmt = select("""
+ROWID, name FROM users WHERE
+ users.ROWID in (SELECT user_from FROM follows WHERE user_to = {{{user_id}}}) AND
+ users.ROWID in (SELECT user_to FROM follows WHERE user_from = {{{user_id}}})""")
assert stmt != null else print_error "Select 'followed_followers' failed with: {error or else "?"}"
var users = new Array[User]
var sql = """
ROWID, name FROM users
WHERE 1 in (SELECT is_in FROM checkins WHERE user = users.ROWID ORDER BY ROWID DESC LIMIT 1)
- AND ROWID in (SELECT user_from FROM follows WHERE user_to = {user_id})
- AND ROWID in (SELECT user_to FROM follows WHERE user_from = {user_id})"""
+ AND ROWID in (SELECT user_from FROM follows WHERE user_to = {{{user_id}}})
+ AND ROWID in (SELECT user_to FROM follows WHERE user_from = {{{user_id}}})"""
var stmt = select(sql)
if stmt == null then
# Close this connection to the DB and all open statements
fun close
do
+ if not is_open then return
+
is_open = false
# close open statements
fun last_insert_rowid: Int do return native_connection.last_insert_rowid
end
-# A prepared Sqlite3 statement, created from `Sqlite3DB::prepare` or `Sqlite3DB::select`
+# Prepared Sqlite3 statement
+#
+# Instances of this class are created from `Sqlite3DB::prepare` and
+# its shortcuts: `create_table`, `insert`, `replace` and `select`.
+# The results should be explored with an `iterator`,
+# and each call to `iterator` resets the request.
+# If `close_with_iterator` the iterator calls `close`
+# on this request upon finishing.
class Statement
private var native_statement: NativeStatement
# Is this statement usable?
var is_open = true
+ # Should any `iterator` close this statement on `Iterator::finish`?
+ #
+ # If `true`, the default, any `StatementIterator` created by calls to
+ # `iterator` invokes `close` on this request when finished iterating.
+ # Otherwise, `close` must be called manually.
+ var close_with_iterator = true is writable
+
# Close and finalize this statement
fun close
do
+ if not is_open then return
+
is_open = false
native_statement.finalize
end
is_ok = false
end
end
+
+ redef fun finish do if statement.close_with_iterator then statement.close
end
# A data type supported by Sqlite3