Posted to tcl by colin at Tue Jan 31 01:52:47 GMT 2012view raw

  1. oo::class create ::tdbc::skeleton::resultset {
  2. # columns - a list of the names of the columns in the result.
  3. method columns {} {
  4. }
  5.  
  6. # nextdict variableName - store the next row of the result set in the given variable
  7. # in caller's scope, in the form of a dictionary that maps column names to values.
  8. method nextdict {variableName} {
  9. }
  10.  
  11. # nextlist variableName - store the next row of the result set in the given variable
  12. # in caller's scope, in the form of a list of cells.
  13. method nextlist {variableName} {
  14. }
  15.  
  16. # rowcount - count of rows affected by the statement,
  17. # or -1 if the count of rows has not been determined.
  18. method rowcount {} {
  19. }
  20.  
  21. superclass tdbc::resultset
  22. constructor {statement args} {
  23. # Constructor accepts a statement and an optional dictionary of substituted parameters
  24. # execute the statement against the database.
  25. # If the dictionary is not supplied, then the default is to get params
  26. # from variables in the caller's scope).
  27. next
  28. if {[llength $args] == 1} {
  29. set args [lindex $args 0]
  30. }
  31. uplevel 1 [list {*}[namespace code {my init}] $statement {*}$args]
  32. }
  33. }
  34.  
  35. oo::class create tdbc::skeleton::statement {
  36. method params {} {
  37. # return a description of the names and expected data types of the parameters of [self]
  38. # MUST be a dictionary whose keys are the names of the parameters, values dictionaries.
  39. # The keys of the subdictionaries MUST include:
  40. # name:
  41. # type:
  42. # precision:
  43. # scale:
  44. # nullable:
  45. # direction: {in out inout}
  46. variable params
  47. set result $params
  48. foreach {n v} $result {
  49. if {![llength $v]} {
  50. # there is no value for this parameter - calculate it
  51. }
  52. }
  53. return $result
  54. }
  55.  
  56. method paramtype {name args} {
  57. set args [lassign $args type]
  58. if {$type in {in out inout}} {
  59. set direction $type
  60. set args [lassign [$args type]]
  61. } else {
  62. set direction inout
  63. }
  64.  
  65. if {$type ni {bigint binary bit char date
  66. decimal double float integer
  67. longvarbinary longvarchar numeric real
  68. time timestamp smallint tinyint varbinary varchar}} {
  69. error "$type invalid"
  70. }
  71. set precision 0; set scale 0
  72. lassign $args precision scale
  73. # now do something with name, type, direction, precision and scale
  74. # Implementors of database APIs SHOULD make every effort to do appropriate type introspection
  75. # so that programmers can avoid needing to include explicit type information in their SQL statements.
  76. }
  77.  
  78. superclass tdbc::statement
  79. constructor {connection sqlcode args} {
  80. next
  81.  
  82. if {[llength $args] == 1} {
  83. set args [lindex $args 0]
  84. }
  85.  
  86. variable params {}
  87. variable sql $sqlcode
  88. foreach token [::tdbc::tokenize $sqlcode] {
  89. if {[string index $token 0] in {$ : @}} {
  90. dict set params [string range $token 1 end] {}
  91. }
  92. }
  93. }
  94. }
  95.  
  96. oo::class create tdbc::skeleton {
  97. # Transactions
  98. method starttransaction {} {
  99. # Begins an atomic transaction on the database.
  100. # If the underlying database does not implement atomic transactions or rollback,
  101. # the starttransaction subcommand MUST throw an error reporting the fact.
  102.  
  103. # If the underlying database does not implement nested transactions,
  104. # a starttransaction command that is executed when there is a transaction already in progress
  105. # (started, but neither committed nor rolled back) MUST result in an error.
  106. error "[info object class [self]] does not support transactions"
  107. }
  108. method commit {} {
  109. # Commits a transaction to the database, making the changes durable.
  110. }
  111. method rollback {} {
  112. # Rolls back a transaction against the database, cancelling any changes made during the transaction.
  113. }
  114.  
  115. # Statements
  116.  
  117. method preparecall {call} {
  118. # Some database interfaces have a different API to stored procedures than to ordinary SQL statements.
  119. # These databases may need a separate type of statement object from the one that implements ordinary
  120. # statements.
  121. # This object can be managed as a statement owned by the connection by using the preparecall method
  122. }
  123.  
  124. method statementCreate {name self sqlcode} {
  125. tdbc::skeleton::statement create $name [self] $sqlcode
  126. }
  127.  
  128. # Structure and Configuration
  129.  
  130. method configure {args} {
  131. # args are of the form -option value ....
  132. # -encoding name
  133. # -isolation {readuncommitted readcommitted repeatableread serializable readonly}
  134. # -timeout ms
  135. # -readonly boolean
  136. }
  137.  
  138. destructor {
  139. # dismiss the connection to the database and clean up associated system resources
  140. # If there is an uncommitted transaction, it SHOULD be rolled back.
  141. # Any handles to other objects associated with the database SHOULD become invalid.
  142. }
  143.  
  144. superclass tdbc::connection
  145. constructor {args} {
  146. next
  147.  
  148. # perform connection and configuration
  149. }
  150. }