Module: sql-implementation Author: eec Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND // $HopeName: !diagnostic.dylan(D-kan.3) $ define function detail-info-not-available(detail-info :: ) => (str :: ) let msg = "information not available"; signal(msg); msg; end function; //---------- Diagnostic Detail ---------- define open abstract class () constant class slot class-code :: , required-init-keyword: class-code:; constant each-subclass slot subclass-code :: = "000", init-keyword: subclass-code:; constant slot condition-number :: = 1, init-keyword: condition-number:; constant slot possible-explanation :: = make(); end class; define method default-handler(diagnostic :: ) // Since is a subclass of , a signalled diagnostic // will be dropped on the floor (similar to a warning) and the code will // continue to execute. An unhandled-diagnostic is an error so the debugger // will take notice of it. error(make(, diagnostic: diagnostic)); end method default-handler; define open class () keyword class-code: = ""; keyword subclass-code: = ""; constant slot sqlstate :: = "", init-keyword: sqlstate:; end class; //---*** andrewa: not used, for some reason ignore(sqlstate); define open generic conditions-not-recorded?(diag :: ) => (not-recorded-status :: ); define method conditions-not-recorded?(diag :: ) => (not-recorded-status :: ) #f; end method; define open generic dynamic-function(diag :: ) => (dynamic-function :: ); define method dynamic-function(diag :: ) => (dynamic-function :: ) detail-info-not-available("dynamic-function"); end method; define open generic row-count(diag :: ) => (count :: ); define method row-count(diag :: ) => (count :: ) 0; end method; define open generic command-function(diag :: ) => (command-function :: ); define method command-function(diag :: ) => (command-function :: ) detail-info-not-available("command-function"); end method; define open generic returned-sqlstate(diag :: ) => (sqlstate :: ); define method returned-sqlstate(diag :: ) => (sqlstate :: ) detail-info-not-available("returned-sqlstate"); end method; define open generic class-origin(diag :: ) => (class-origin :: ); define method class-origin(diag :: ) => (class-origin :: ) detail-info-not-available("class-origin"); end method; define open generic subclass-origin(diag :: ) => (subclass-origin :: ); define method subclass-origin(diag :: ) => (subclass-origin :: ); detail-info-not-available("subclass-origin"); end method; define open generic constraint-catalog(diag :: ) => (constraint-catalog :: ); define method constraint-catalog(diag :: ) => (constraint-catalog :: ); detail-info-not-available("constraint-catalog"); end method; define open generic constraint-schema(diag :: ) => (constraint-schema :: ); define method constraint-schema(diag :: ) => (constraint-schema :: ); detail-info-not-available("constraint-schema"); end method; define open generic constraint-name(diag :: ) => (constraint-name :: ); define method constraint-name(diag :: ) => (constraint-name :: ); detail-info-not-available("constraint-name"); end method; define open generic connection-name(diag :: ) => (connection-name :: ); define method connection-name(diag :: ) => (connection-name :: ); detail-info-not-available("connection-name"); end method; define open generic environment-name(diag :: ) => (env-name :: ); define method environment-name(diag :: ) => (env-name :: ); detail-info-not-available("environment-name"); end method; define open generic catalog-name(diag :: ) => (catalog-name :: ); define method catalog-name(diag :: ) => (catalog-name :: ); detail-info-not-available("catalog-name"); end method; define open generic schema-name(diag :: ) => (schema-name :: ); define method schema-name(diag :: ) => (schema-name :: ); detail-info-not-available("schema-name"); end method; define open generic table-name(diag :: ) => (table-name :: ); define method table-name(diag :: ) => (table-name :: ); detail-info-not-available("table-name"); end method; define open generic column-name(diag :: ) => (column-name :: ); define method column-name(diag :: ) => (column-name :: ); detail-info-not-available("column-name"); end method; define open generic cursor-name(diag :: ) => (cursor-name :: ); define method cursor-name(diag :: ) => (cursor-name :: ); detail-info-not-available("cursor-name"); end method; define open generic message-text(diag :: ) => (message-text :: ); define method message-text(diag :: ) => (message-text :: ); detail-info-not-available("message-text"); end method; define open generic next-dbms-diagnostic(diag :: ) => (next-diagnostic :: false-or()); define method next-dbms-diagnostic(diag :: ) => (next-diagnostic :: false-or()) #f; end method; define open generic diagnostic-to-string(diag :: ) => (string :: ); define method diagnostic-to-string(diag :: ) => (string :: ) format-to-string("Diagnostic - \n" " Conditions not recorded: %=\n" " Command function: %=\n" " Dynamic function: %=\n" " Row count: %=\n" " Condition/Diagnostic number: %=\n" " Returned SQLState: %=\n" " Class origin: %=\n" " Subclass origin: %=\n" " Constraint catalog: %=\n" " Constraint schema: %=\n" " Constraint name: %=\n" " Connection name: %=\n" " Environment name: %=\n" " Catalog name: %=\n" " Schema name: %=\n" " Table name: %=\n" " Column name: %=\n" " Message Text: %=\n", diag.conditions-not-recorded?, diag.command-function, diag.dynamic-function, diag.row-count, diag.condition-number, diag.returned-sqlstate, diag.class-origin, diag.subclass-origin, diag.constraint-catalog, diag.constraint-schema, diag.constraint-name, diag.connection-name, diag.environment-name, diag.catalog-name, diag.schema-name, diag.table-name, diag.column-name, diag.message-text) end method; define method condition-to-string (diag :: ) => (string :: false-or()) let diag-string :: = make(); let test-diag = diag; while (test-diag ~= #f) diag-string := concatenate(diag-string, diagnostic-to-string(test-diag)); test-diag := next-dbms-diagnostic(test-diag); end while; diag-string end method condition-to-string; //---------- Specific Diagnostic Detail ---------- define open class () keyword class-code: = "3C"; end class; define open class () keyword class-code: = "21"; end class; define open class () keyword class-code: = "08"; end class; define open class () keyword subclass-code: = "003"; end class; define open class () keyword subclass-code: = "006"; end class; define open class () keyword subclass-code: = "002"; end class; define open class () keyword subclass-code: = "001"; end class; define open class () keyword subclass-code: = "004"; end class; define open class () keyword subclass-code: = "007"; end class; define open class () keyword class-code: = "09"; end class; define open class () keyword class-code: = "22"; end class; define open class () keyword subclass-code: = "021"; end class; define open class () keyword subclass-code: = "008"; end class; define open class () keyword subclass-code: = "012"; end class; define open class () keyword subclass-code: = "005"; end class; define open class () keyword subclass-code: = "022"; end class; define open class () keyword subclass-code: = "015"; end class; define open class () keyword subclass-code: = "018"; end class; define open class () keyword subclass-code: = "007"; end class; define open class () keyword subclass-code: = "019"; end class; define open class () keyword subclass-code: = "025"; end class; define open class () keyword subclass-code: = "006"; end class; define open class () keyword subclass-code: = "023"; end class; define open class () keyword subclass-code: = "009"; end class; define open class () keyword subclass-code: = "002"; end class; define open class () keyword subclass-code: = "003"; end class; define open class () keyword subclass-code: = "026"; end class; define open class () keyword subclass-code: = "001"; end class; define open class () keyword subclass-code: = "011"; end class; define open class () keyword subclass-code: = "027"; end class; define open class () keyword subclass-code: = "024"; end class; define open class () keyword class-code: = "2B"; end class; define open class () keyword class-code: = "07"; end class; define open class () keyword subclass-code: = "003"; end class; define open class () keyword subclass-code: = "008"; end class; define open class () keyword subclass-code: = "009"; end class; define open class () keyword subclass-code: = "005"; end class; define open class () keyword subclass-code: = "006"; end class; define open class () keyword subclass-code: = "001"; end class; define open class () keyword subclass-code: = "002"; end class; define open class () keyword subclass-code: = "004"; end class; define open class () keyword subclass-code: = "007"; end class; define open class () keyword class-code: = "0A"; end class; define open class () keyword subclass-code: = "001"; end class; define open class () keyword class-code: = "23"; end class; define open class () keyword class-code: = "28"; end class; define open class () keyword class-code: = "3D"; end class; define open class () keyword class-code: = "2C"; end class; define open class () keyword class-code: = "35"; end class; define open class () keyword class-code: = "34"; end class; define open class () keyword class-code: = "3F"; end class; define open class () keyword class-code: = "33"; end class; define open class () keyword class-code: = "26"; end class; define open class () keyword class-code: = "25"; end class; define open class () keyword class-code: = "2D"; end class; define open class () keyword class-code: = "02"; end class; define open class () keyword class-code: = "HZ"; end class; define open class () keyword class-code: = "00"; end class; define open class () keyword class-code: = "42"; end class; define open class () keyword class-code: = "2A"; end class; define open class () keyword class-code: = "37"; end class; define open class () keyword class-code: = "40"; end class; define open class () keyword subclass-code: = "002"; end class; define open class () keyword subclass-code: = "001"; end class; define open class () keyword subclass-code: = "003"; end class; define open class () keyword class-code: = "27"; end class; define open class () keyword class-code: = "01"; end class; define open class () keyword subclass-code: = "001"; end class; define open class () keyword subclass-code: = "002"; end class; define open class () keyword subclass-code: = "008"; end class; define open class () keyword subclass-code: = "005"; end class; define open class () keyword subclass-code: = "003"; end class; define open class () keyword subclass-code: = "007"; end class; define open class () keyword subclass-code: = "006"; end class; define open class () keyword subclass-code: = "00A"; end class; define open class () keyword subclass-code: = "009"; end class; define open class () keyword subclass-code: = "004"; end class; define open class () keyword class-code: = "44"; end class; //-------------------- Diagnostic Table -------------------- define class () constant slot diagnostics :: = make(); constant slot general-key :: , required-init-keyword: general-key:; slot diagnostics-installed? :: = #f; constant slot installation-functions :: = make(); end class ; define constant $general-dbms = #"general-dbms"; define constant $diagnostic-table :: = make(, general-key: $general-dbms); define function register-diagnostic-installer (function :: ) => () push-last($diagnostic-table.installation-functions, function) end function register-diagnostic-installer; define function install-diagnostics (table :: ) => () install-general-diagnostics(table); for (fn in table.installation-functions) fn(table); end for; end function; define function install-diagnostic-key (key :: ) => () $diagnostic-table.diagnostics[key] := make(); end function install-diagnostic-key; define function install-diagnostic (table :: , class :: subclass(), #key key :: = table.general-key) => () let diagnostic = make(class); let sqlstate = concatenate(diagnostic.class-code, diagnostic.subclass-code); table.diagnostics[key][sqlstate] := class; end function install-diagnostic; define function install-general-diagnostics(table :: ) => () debug-assert(found?(element(table.diagnostics, table.general-key, default: $unfound)), "There is no subset of diagnostic table for a general dbms."); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); install-diagnostic(table, ); end function; //-------------------- find-diagnostic not -------------------- // Right now, the ODBC installs ODBC specific versions of the general // diagnostic details and the ODBC library does not add anything // specific. Any overlap probably should be removed and this function // should be modified to search for the diagnostic in the general // table in the event it isn't found in the specific table. define function find-diagnostic (table :: , diagnostic-set-key :: , sqlstate :: ) => (diagnostic-detail-class :: ) if (table.diagnostics-installed? = #f) install-diagnostic-key(table.general-key); install-diagnostics(table); table.diagnostics-installed? := #t; end if; let subtable = element(table.diagnostics, diagnostic-set-key, default: $unfound); debug-assert(found?(subtable), "Diagnostic table for key % not found.", diagnostic-set-key); let diag-class = element(subtable, sqlstate, default: $unfound); if (found?(diag-class)) diag-class else let general-table = element(table.diagnostics, table.general-key, default: $unfound); assert(found?(general-table), "The general diagnostic table was not found."); let diag-class = element(general-table, sqlstate, default: $unfound); if (found?(diag-class)) diag-class; else $unfound; end if; end if; end function;