| 'use strict'; |
| const { skipIfSQLiteMissing } = require('../common'); |
| skipIfSQLiteMissing(); |
| const assert = require('node:assert'); |
| const { DatabaseSync } = require('node:sqlite'); |
| const { suite, test } = require('node:test'); |
| |
| suite('StatementSync.prototype.columns()', () => { |
| test('returns column metadata for core SQLite types', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec(`CREATE TABLE test ( |
| col1 INTEGER, |
| col2 REAL, |
| col3 TEXT, |
| col4 BLOB, |
| col5 NULL |
| )`); |
| const stmt = db.prepare('SELECT col1, col2, col3, col4, col5 FROM test'); |
| assert.deepStrictEqual(stmt.columns(), [ |
| { |
| __proto__: null, |
| column: 'col1', |
| database: 'main', |
| name: 'col1', |
| table: 'test', |
| type: 'INTEGER', |
| }, |
| { |
| __proto__: null, |
| column: 'col2', |
| database: 'main', |
| name: 'col2', |
| table: 'test', |
| type: 'REAL', |
| }, |
| { |
| __proto__: null, |
| column: 'col3', |
| database: 'main', |
| name: 'col3', |
| table: 'test', |
| type: 'TEXT', |
| }, |
| { |
| __proto__: null, |
| column: 'col4', |
| database: 'main', |
| name: 'col4', |
| table: 'test', |
| type: 'BLOB', |
| }, |
| { |
| __proto__: null, |
| column: 'col5', |
| database: 'main', |
| name: 'col5', |
| table: 'test', |
| type: null, |
| }, |
| ]); |
| }); |
| |
| test('supports statements using multiple tables', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec(` |
| CREATE TABLE test1 (value1 INTEGER); |
| CREATE TABLE test2 (value2 INTEGER); |
| `); |
| const stmt = db.prepare('SELECT value1, value2 FROM test1, test2'); |
| assert.deepStrictEqual(stmt.columns(), [ |
| { |
| __proto__: null, |
| column: 'value1', |
| database: 'main', |
| name: 'value1', |
| table: 'test1', |
| type: 'INTEGER', |
| }, |
| { |
| __proto__: null, |
| column: 'value2', |
| database: 'main', |
| name: 'value2', |
| table: 'test2', |
| type: 'INTEGER', |
| }, |
| ]); |
| }); |
| |
| test('supports column aliases', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec(`CREATE TABLE test (value INTEGER)`); |
| const stmt = db.prepare('SELECT value AS foo FROM test'); |
| assert.deepStrictEqual(stmt.columns(), [ |
| { |
| __proto__: null, |
| column: 'value', |
| database: 'main', |
| name: 'foo', |
| table: 'test', |
| type: 'INTEGER', |
| }, |
| ]); |
| }); |
| |
| test('supports column expressions', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec(`CREATE TABLE test (value INTEGER)`); |
| const stmt = db.prepare('SELECT value + 1, value FROM test'); |
| assert.deepStrictEqual(stmt.columns(), [ |
| { |
| __proto__: null, |
| column: null, |
| database: null, |
| name: 'value + 1', |
| table: null, |
| type: null, |
| }, |
| { |
| __proto__: null, |
| column: 'value', |
| database: 'main', |
| name: 'value', |
| table: 'test', |
| type: 'INTEGER', |
| }, |
| ]); |
| }); |
| |
| test('supports subqueries', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec(`CREATE TABLE test (value INTEGER)`); |
| const stmt = db.prepare('SELECT * FROM (SELECT * FROM test)'); |
| assert.deepStrictEqual(stmt.columns(), [ |
| { |
| __proto__: null, |
| column: 'value', |
| database: 'main', |
| name: 'value', |
| table: 'test', |
| type: 'INTEGER', |
| }, |
| ]); |
| }); |
| |
| test('supports statements that do not return data', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec('CREATE TABLE test (value INTEGER)'); |
| const stmt = db.prepare('INSERT INTO test (value) VALUES (?)'); |
| assert.deepStrictEqual(stmt.columns(), []); |
| }); |
| |
| test('throws if the statement is finalized', () => { |
| const db = new DatabaseSync(':memory:'); |
| db.exec('CREATE TABLE test (value INTEGER)'); |
| const stmt = db.prepare('SELECT value FROM test'); |
| db.close(); |
| assert.throws(() => { |
| stmt.columns(); |
| }, /statement has been finalized/); |
| }); |
| }); |