1 /++ 2 D2SQLite3 provides a thin and convenient wrapper around the SQLite C API. 3 4 Features: 5 $(UL 6 $(LI Use reference-counted structs (`Database`, `Statement`) instead of SQLite objects 7 pointers.) 8 $(LI Run multistatement SQL code with `Database.run()`.) 9 $(LI Use built-in integral types, floating point types, `string`, `immutable(ubyte)[]` and 10 `Nullable` types directly: conversions to and from SQLite types is automatic and GC-safe.) 11 $(LI Bind multiple values to a prepare statement with `Statement.bindAll()` or 12 `Statement.inject()`. It's also possible to bind the fields of a struct automatically with 13 `Statement.inject()`.) 14 $(LI Handle the results of a query as a range of `Row`s, and the columns of a row 15 as a range of `ColumnData` (equivalent of a `Variant` fit for SQLite types).) 16 $(LI Access the data in a result row directly, by index or by name, 17 with the `Row.peek!T()` methods.) 18 $(LI Make a struct out of the data of a row with `Row.as!T()`.) 19 $(LI Register D functions as SQLite callbacks, with `Database.setUpdateHook()` $(I et al).) 20 $(LI Create new SQLite functions, aggregates or collations out of D functions or delegate, 21 with automatic type converions, with `Database.createFunction()` $(I et al).) 22 $(LI Store all the rows and columns resulting from a query at once with the `cached` function 23 (sometimes useful even if not memory-friendly...).) 24 $(LI Use an unlock notification when two or more connections access the same database in 25 shared-cache mode, either using SQLite's dedicated API (sqlite_unlock_notify) or using an 26 emulated equivalent.) 27 ) 28 29 Authors: 30 Nicolas Sicard (biozic) and other contributors at $(LINK https://github.com/biozic/d2sqlite3) 31 32 Copyright: 33 Copyright 2011-18 Nicolas Sicard. 34 35 License: 36 $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 37 +/ 38 module d2sqlite3; 39 40 public import d2sqlite3.library; 41 public import d2sqlite3.database; 42 public import d2sqlite3.statement; 43 public import d2sqlite3.results; 44 public import d2sqlite3.sqlite3; 45 46 /// 47 unittest // Documentation example 48 { 49 // Note: exception handling is left aside for clarity. 50 import d2sqlite3; 51 import std.typecons : Nullable; 52 53 // Open a database in memory. 54 auto db = Database(":memory:"); 55 56 // Create a table 57 db.run("DROP TABLE IF EXISTS person; 58 CREATE TABLE person ( 59 id INTEGER PRIMARY KEY, 60 name TEXT NOT NULL, 61 score FLOAT 62 )"); 63 64 // Prepare an INSERT statement 65 Statement statement = db.prepare( 66 "INSERT INTO person (name, score) 67 VALUES (:name, :score)" 68 ); 69 70 // Bind values one by one (by parameter name or index) 71 statement.bind(":name", "John"); 72 statement.bind(2, 77.5); 73 statement.execute(); 74 statement.reset(); // Need to reset the statement after execution. 75 76 // Bind muliple values at the same time 77 statement.bindAll("John", null); 78 statement.execute(); 79 statement.reset(); 80 81 // Bind, execute and reset in one call 82 statement.inject("Clara", 88.1); 83 84 // Count the changes 85 assert(db.totalChanges == 3); 86 87 // Count the Johns in the table. 88 auto count = db.execute("SELECT count(*) FROM person WHERE name == 'John'") 89 .oneValue!long; 90 assert(count == 2); 91 92 // Read the data from the table lazily 93 ResultRange results = db.execute("SELECT * FROM person"); 94 foreach (Row row; results) 95 { 96 // Retrieve "id", which is the column at index 0, and contains an int, 97 // e.g. using the peek function (best performance). 98 auto id = row.peek!long(0); 99 100 // Retrieve "name", e.g. using opIndex(string), which returns a ColumnData. 101 auto name = row["name"].as!string; 102 103 // Retrieve "score", which is at index 2, e.g. using the peek function, 104 // using a Nullable type 105 auto score = row.peek!(Nullable!double)(2); 106 if (!score.isNull) 107 { 108 // ... 109 } 110 } 111 }