! Copyright (C) 2008 Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: classes kernel help.markup help.syntax sequences alien assocs strings math multiline quotations ; IN: db HELP: db { $description "The " { $snippet "db" } " class is the superclass of all other database classes. It stores a " { $snippet "handle" } " to the database as well as insert, update, and delete queries." } ; HELP: new-db { $values { "class" class } { "obj" object } } { $description "Creates a new database object from a given class." } ; HELP: make-db* { $values { "object" object } { "db" object } { "db" object } } { $description "Takes a sequence of parameters specific to each database and a class name of the database, and constructs a new database object." } ; HELP: make-db { $values { "object" object } { "class" class } { "db" db } } { $description "Takes a sequence of parameters specific to each database and a class name of the database, and constructs a new database object." } ; HELP: db-open { $values { "db" db } { "db" db } } { $description "Opens a database using the configuration data stored in a " { $link db } " tuple." } ; HELP: db-close { $values { "handle" alien } } { $description "Closes a database using the handle provided." } ; HELP: dispose-statements { $values { "assoc" assoc } } { $description "Disposes an associative list of statements." } ; HELP: db-dispose { $values { "db" db } } { $description "Disposes of all the statements stored in the " { $link db } " object." } ; HELP: statement { $description "A " { $snippet "statement" } " stores the information about a statemen, such as the SQL statement text, the in/out parameters, and type information." } ; HELP: simple-statement { $description } ; HELP: prepared-statement { $description } ; HELP: result-set { $description "An object encapsulating a raw SQL result object. There are two ways in which a result set can be accessed, but they are specific to the database backend in use." { $subsection "db-random-access-result-set" } { $subsection "db-sequential-result-set" } } ; HELP: init-result-set { $values { "result-set" result-set } } { $description "" } ; HELP: new-result-set { $values { "query" "a query" } { "handle" alien } { "class" class } { "result-set" result-set } } { $description "Creates a new " { $link result-set } " object of type " { $snippet "class" } "." } ; HELP: new-statement { $values { "sql" string } { "in" sequence } { "out" sequence } { "class" class } { "statement" statement } } { $description "Makes a new statement object from the given parameters." } ; HELP: { $values { "string" string } { "in" sequence } { "out" sequence } { "statement" statement } } { $description "Makes a new simple statement object from the given parameters." } ; HELP: { $values { "string" string } { "in" sequence } { "out" sequence } { "statement" statement } } { $description "Makes a new prepared statement object from the given parameters." } ; HELP: prepare-statement { $values { "statement" statement } } { $description "For databases which implement a method on this generic, it does some internal processing to ready the statement for execution." } ; HELP: bind-statement* { $values { "statement" statement } } { $description "" } ; HELP: low-level-bind { $values { "statement" statement } } { $description "" } ; HELP: bind-tuple { $values { "tuple" tuple } { "statement" statement } } { $description "" } ; HELP: query-results { $values { "query" object } { "result-set" result-set } } { $description "Returns a " { $link result-set } " object representing the reults of a SQL query." } ; HELP: #rows { $values { "result-set" result-set } { "n" integer } } { $description "Returns the number of rows in a result set." } ; HELP: #columns { $values { "result-set" result-set } { "n" integer } } { $description "Returns the number of columns in a result set." } ; HELP: row-column { $values { "result-set" result-set } { "column" integer } { "obj" object } } { $description "Returns the value indexed by " { $snippet "column" } " in the current row of a " { $link result-set } "." } ; HELP: row-column-typed { $values { "result-set" result-set } { "column" integer } { "sql" "sql" } } { $description "Returns the value indexed by " { $snippet "column" } " in the current row of a " { $link result-set } " and converts the result based on a type stored in the " { $link result-set } "'s " { $slot "out-params" } "." } ; HELP: advance-row { $values { "result-set" result-set } } { $description "Advanced the pointer to an underlying SQL result set stored in a " { $link result-set } " object." } ; HELP: more-rows? { $values { "result-set" result-set } { "?" "a boolean" } } { $description "Returns true if the " { $link result-set } " has more rows to traverse." } ; HELP: execute-statement* { $values { "statement" statement } { "type" object } } { $description } ; HELP: execute-one-statement { $values { "statement" null } } { $description "" } ; HELP: execute-statement { $values { "statement" statement } } { $description "" } ; HELP: begin-transaction { $description "Begins a new transaction. User code should make use of the " { $link with-transaction } " combinator." } ; HELP: bind-statement { $values { "obj" object } { "statement" null } } { $description "" } ; HELP: commit-transaction { $description "Commits a transaction. User code should make use of the " { $link with-transaction } " combinator." } ; HELP: default-query { $values { "query" null } { "result-set" null } } { $description "" } ; HELP: in-transaction { $description "A variable that is set true when a transaction is in progress." } ; HELP: in-transaction? { $values { "?" "a boolean" } } { $description "Returns true if there is currently a transaction in progress in this scope." } ; HELP: query-each { $values { "statement" null } { "quot" quotation } } { $description "" } ; HELP: query-map { $values { "statement" null } { "quot" quotation } { "seq" sequence } } { $description "" } ; HELP: rollback-transaction { $description "Rolls back a transaction; no data is committed to the database. User code should make use of the " { $link with-transaction } " combinator." } ; HELP: sql-command { $values { "sql" string } } { $description "Executes a SQL string using the databse in the " { $link db } " symbol." } ; HELP: sql-query { $values { "sql" string } { "rows" "an array of arrays of strings" } } { $description "Runs a SQL query of raw text in the database in the " { $link db } " symbol. Each row is returned as an array of strings; no type-conversions are done on the resulting data." } ; { sql-command sql-query } related-words HELP: sql-row { $values { "result-set" result-set } { "seq" sequence } } { $description "Returns the current row in a " { $link result-set } " as an array of strings." } ; HELP: sql-row-typed { $values { "result-set" result-set } { "seq" sequence } } { $description "Returns the current row in a " { $link result-set } " as an array of typed Factor objects." } ; { sql-row sql-row-typed } related-words HELP: with-db { $values { "seq" sequence } { "class" class } { "quot" quotation } } { $description "Calls the quotation with a database bound to the " { $link db } " symbol. The database called is based on the " { $snippet "class" } " with the " } ; HELP: with-transaction { $values { "quot" quotation } } { $description "" } ; ARTICLE: "db" "Database library" { $subsection "db-custom-database-combinators" } { $subsection "db-protocol" } { $subsection "db-result-sets" } { $subsection "db-lowlevel-tutorial" } "Higher-level database:" { $vocab-subsection "Database types" "db.types" } { $vocab-subsection "High-level tuple/database integration" "db.tuples" } ! { $subsection "db-tuples" } ! { $subsection "db-tuples-protocol" } ! { $subsection "db-tuples-tutorial" } "Supported database backends:" { $vocab-subsection "SQLite" "db.sqlite" } { $vocab-subsection "PostgreSQL" "db.postgresql" } "To add support for another database to Factor:" { $subsection "db-porting-the-library" } ; ARTICLE: "db-random-access-result-set" "Random access result sets" "Random-access result sets do not have to be traversed in order. For instance, PostgreSQL's result set object can be accessed as a matrix with i,j coordinates." $nl "Databases which work in this way must provide methods for the following traversal words:" { $subsection #rows } { $subsection #columns } { $subsection row-column } { $subsection row-column-typed } ; ARTICLE: "db-sequential-result-set" "Sequential result sets" "Sequential result sets can be iterated one element after the next. SQLite's result sets offer this method of traversal." $nl "Databases which work in this way must provide methods for the following traversal words:" { $subsection more-rows? } { $subsection advance-row } { $subsection row-column } { $subsection row-column-typed } ; ARTICLE: "db-result-sets" "Result sets" "Result sets are the encapsulated, database-specific results from a SQL query." $nl "Two possible protocols for iterating over result sets exist:" { $subsection "db-random-access-result-set" } { $subsection "db-sequential-result-set" } "Query the number of rows or columns:" { $subsection #rows } { $subsection #columns } "Traversing a result set:" { $subsection advance-row } { $subsection more-rows? } "Pulling out a single row of results:" { $subsection row-column } { $subsection row-column-typed } ; ARTICLE: "db-protocol" "Low-level database protocol" "The high-level protocol (see " { $vocab-link "db.tuples" } ") uses this low-level protocol for executing statements and queries." ; ARTICLE: "db-lowlevel-tutorial" "Low-level database tutorial" "Although Factor makes integrating a database with its object system easy (see " { $vocab-link "db.tuples" } "), sometimes you may want to write SQL directly and get the results back as arrays of strings, for instance, when interfacing with a legacy database that doesn't easily map to " { $snippet "tuples" } "." ; ARTICLE: "db-porting-the-library" "Porting the database library" "This section is not yet written." ; ARTICLE: "db-custom-database-combinators" "Custom database combinators" "Every database library requires some effort on the programmer's part to initialize and open a database. SQLite uses files on your harddisk, so a simple pathname is all the setup required. With PostgreSQL, you log in to a networked server as a user on a specfic port." $nl "Make a " { $snippet "with-" } " word to open, close, and use your database." { $code <" USING: db.sqlite db io.files ; : with-my-database ( quot -- ) { "my-database.db" temp-file } sqlite-db rot with-db ; "> } ; ABOUT: "db"