Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  test_sqlite_carray.js

  Sprache: JAVA
 

/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */


"use strict";

// head.js provides: Sqlite, do_get_profile

function getConnection(dbName) {
  return Sqlite.openConnection({ path: dbName + ".sqlite" });
}

async function getDummyDatabase(name) {
  let c = await getConnection(name);
  await c.execute(
    "CREATE TABLE dirs (id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT)"
  );
  return c;
}

add_task(async function test_carray_binding() {
  let c = await getDummyDatabase("carray_binding");
  await c.execute("INSERT INTO dirs VALUES (1, 'foo')");
  await c.execute("INSERT INTO dirs VALUES (2, 'bar')");
  await c.execute("INSERT INTO dirs VALUES (3, 'baz')");

  // Named integer array.
  let rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN carray(:ids) ORDER BY id",
    { ids: [13] }
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["foo""baz"]
  );

  // Indexed integer array.
  rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN carray(?1) ORDER BY id",
    [[23]]
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["bar""baz"]
  );

  // Values that satisfy Number.isInteger() — including those that lose their
  // fractional part due to IEEE 754 precision (e.g. 5.0000000000000001 === 5.0)
  // — are bound as integers, not doubles.
  rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN carray(:ids) ORDER BY id",
    // eslint-disable-next-line no-loss-of-precision
    { ids: [1.03.0000000000000001] }
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["foo""baz"]
  );

  // Named string array.
  rows = await c.execute(
    "SELECT id FROM dirs WHERE path IN carray(:paths) ORDER BY id",
    { paths: ["foo""baz"] }
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("id")),
    [13]
  );

  // Named float array.
  await c.execute("CREATE TABLE floats (val REAL)");
  await c.execute("INSERT INTO floats VALUES (1.1)");
  await c.execute("INSERT INTO floats VALUES (2.2)");
  rows = await c.execute(
    "SELECT val FROM floats WHERE val IN carray(:vals) ORDER BY val",
    { vals: [1.12.2] }
  );
  Assert.equal(rows.length, 2);

  // Integer followed by a double: the array is promoted to doubles.
  await c.execute("INSERT INTO floats VALUES (3)");
  rows = await c.execute(
    "SELECT val FROM floats WHERE val IN carray(:vals) ORDER BY val",
    { vals: [31.1] }
  );
  Assert.equal(rows.length, 2);

  // A whole-number double (2.0) satisfies Number.isInteger() and would naively
  // be classified as an integer, but the array is still bound as doubles
  // because subsequent elements are non-integer.
  await c.execute("INSERT INTO floats VALUES (2.0)");
  rows = await c.execute(
    "SELECT val FROM floats WHERE val IN carray(:vals) ORDER BY val",
    { vals: [2.01.12.2] }
  );
  Assert.equal(rows.length, 3);

  // Double followed by an integer: still bound as doubles.
  rows = await c.execute(
    "SELECT val FROM floats WHERE val IN carray(:vals) ORDER BY val",
    { vals: [1.13] }
  );
  Assert.equal(rows.length, 2);

  // Empty array should throw.
  await Assert.rejects(
    c.execute("SELECT path FROM dirs WHERE id IN carray(:ids)", { ids: [] }),
    /Array must not be empty/
  );

  await c.close();
});

add_task(async function test_carray_binding_invalid_inputs() {
  let c = await getDummyDatabase("carray_binding_invalid");
  await c.execute("INSERT INTO dirs VALUES (1, 'foo')");

  // Array with object elements should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[{ id: 1 }]]),
    /Unsupported array element type: object/
  );

  // Array with nested array elements should throw (typeof [] is "object").
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[[12]]]),
    /Unsupported array element type: object/
  );

  // Integer followed by string should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[1"two"]]),
    /All array elements must be of the same type/
  );

  // String followed by integer should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [["one"2]]),
    /All array elements must be of the same type/
  );

  // Array with null element should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[null1]]),
    /Unsupported array element type: object/
  );

  // NaN element should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[1, NaN]]),
    /Array elements must be finite numbers/
  );

  // Positive infinity should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[Infinity]]),
    /Array elements must be finite numbers/
  );

  // Negative infinity should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(?1)", [[-Infinity, 2]]),
    /Array elements must be finite numbers/
  );

  // Array bound to a non-carray query should throw.
  await Assert.rejects(
    c.execute("SELECT id FROM dirs WHERE id = :id", { id: [12] }),
    /Array parameters require carray\(\)/
  );

  // Scalar bound to a carray() parameter should throw.
  await Assert.rejects(
    c.execute("SELECT path FROM dirs WHERE id IN carray(:ids)", { ids: 1 }),
    /carray\(\) parameters must be bound to an array/
  );

  await c.close();
});

add_task(async function test_carray_binding_null_elements() {
  let c = await getDummyDatabase("carray_binding_nulls");

  // null as first element should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(:ids)", { ids: [null12] }),
    /Unsupported array element type: object/
  );

  // null in the middle should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(:ids)", { ids: [1null2] }),
    /Unsupported array element type: object/
  );

  // All-null array should throw.
  await Assert.rejects(
    c.execute("SELECT * FROM carray(:ids)", { ids: [nullnull] }),
    /Unsupported array element type: object/
  );

  await c.close();
});

add_task(async function test_carray_binding_multirow() {
  let c = await getDummyDatabase("carray_binding_multirow");
  await c.execute("INSERT INTO dirs VALUES (1, 'foo')");
  await c.execute("INSERT INTO dirs VALUES (2, 'bar')");
  await c.execute("INSERT INTO dirs VALUES (3, 'baz')");
  await c.execute("INSERT INTO dirs VALUES (4, 'qux')");

  await c.execute("DELETE FROM dirs WHERE id IN carray(:ids)", [
    { ids: [12] },
    { ids: [3] },
  ]);
  let rows = await c.execute("SELECT id FROM dirs ORDER BY id");
  Assert.deepEqual(
    rows.map(r => r.getResultByName("id")),
    [4]
  );

  await c.close();
});

add_task(async function test_carray_binding_syntax_variants() {
  let c = await getDummyDatabase("carray_binding_syntax");
  await c.execute("INSERT INTO dirs VALUES (1, 'foo')");
  await c.execute("INSERT INTO dirs VALUES (2, 'bar')");
  await c.execute("INSERT INTO dirs VALUES (3, 'baz')");

  // Uppercase CARRAY() is valid SQL.
  let rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN CARRAY(:ids) ORDER BY id",
    { ids: [12] }
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["foo""bar"]
  );

  // Bare ? placeholder (anonymous, sequential).
  rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN carray(?) ORDER BY id",
    [[23]]
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["bar""baz"]
  );

  // Bare ? with a preceding scalar param.
  rows = await c.execute(
    "SELECT path FROM dirs WHERE path != ? AND id IN carray(?) ORDER BY id",
    ["foo", [23]]
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["bar""baz"]
  );

  await c.close();
});

add_task(async function test_carray_binding_multiple() {
  let c = await getDummyDatabase("carray_binding_multiple");
  await c.execute("INSERT INTO dirs VALUES (1, 'foo')");
  await c.execute("INSERT INTO dirs VALUES (2, 'bar')");
  await c.execute("INSERT INTO dirs VALUES (3, 'baz')");

  // Two carray() in one query, both named.
  let rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN carray(:ids) AND path IN carray(:paths) ORDER BY id",
    { ids: [123], paths: ["foo""baz"] }
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["foo""baz"]
  );

  // Two bare carray(?) in one query.
  rows = await c.execute(
    "SELECT path FROM dirs WHERE id IN carray(?) AND path IN carray(?) ORDER BY id",
    [
      [123],
      ["foo""baz"],
    ]
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("path")),
    ["foo""baz"]
  );

  await c.close();
});

// This test exercises an extreme edge case of SQLite parameter numbering where
// explicit ?N and bare ? placeholders are interleaved. This is purely to verify
// correct internal behaviour — never write SQL like this in production code.
add_task(async function test_carray_binding_mixed_placeholder_styles() {
  let c = await getDummyDatabase("carray_binding_mixed_placeholders");
  await c.execute("INSERT INTO dirs VALUES (1, 'foo')");
  await c.execute("INSERT INTO dirs VALUES (2, 'bar')");
  await c.execute("INSERT INTO dirs VALUES (3, 'baz')");

  // 6 carray() references but only 4 distinct parameter slots:
  //   ?1=slot0, ?=slot1, ?=slot2, ?2=slot1 (same as first bare ?),
  //   ?=slot3, ?3=slot2 (same as second bare ?)
  // The intersections narrow the result down to id=1 only.
  let rows = await c.execute(
    `SELECT id FROM dirs
       WHERE id IN carray(?1)
         AND id IN carray(?)
         AND id IN carray(?)
         AND id IN carray(?2)
         AND id IN carray(?)
         AND id IN carray(?3)
       ORDER BY id`,
    [
      [123],
      [12],
      [13],
      [123],
    ]
  );
  Assert.deepEqual(
    rows.map(r => r.getResultByName("id")),
    [1]
  );

  await c.close();
});

Messung V0.5 in Prozent
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002