Changeset 62
- Timestamp:
- 03/04/07 00:12:10 (2 years ago)
- Files:
-
- branches/0.3-dev/dbi/ColInfo.d (added)
- branches/0.3-dev/dbi/Database.d (modified) (2 diffs)
- branches/0.3-dev/dbi/Result.d (modified) (2 diffs)
- branches/0.3-dev/dbi/Row.d (modified) (3 diffs)
- branches/0.3-dev/dbi/ib/imp.d (modified) (1 diff)
- branches/0.3-dev/dbi/mssql/MssqlDatabase.d (modified) (1 diff)
- branches/0.3-dev/dbi/mssql/MssqlResult.d (modified) (8 diffs)
- branches/0.3-dev/dbi/mssql/build.brf (added)
- branches/0.3-dev/dbi/mssql/imp.d (modified) (2 diffs)
- branches/0.3-dev/dbi/mssql/rebuild.rf (added)
- branches/0.3-dev/dbi/mssql/test2.d (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/0.3-dev/dbi/Database.d
r59 r62 218 218 } 219 219 220 /+ 220 221 private class TestDatabase : Database { 221 222 void connect (char[] params, char[] username = null, char[] password = null) {} … … 226 227 deprecated char[] getErrorMessage () {return "";} 227 228 } 229 +/ 228 230 229 231 unittest { branches/0.3-dev/dbi/Result.d
r59 r62 8 8 module dbi.Result; 9 9 10 private import dbi.Row; 10 private import dbi.ColInfo, dbi.Row; 11 private import tango.io.Stdout; 11 12 12 13 /** … … 39 40 abstract Row fetchRow (); 40 41 42 43 41 44 /** 42 * Get all of the remaining rows from a result set. 43 * 44 * Returns: 45 * An array of Row objects with the queried information. 45 * for foreach use 46 46 */ 47 Row[] fetchAll () {48 Row[] rows;49 Row row;50 while ((row = fetchRow()) !is null) {51 rows ~= row;47 int opApply(int delegate(inout Row) dg) { 48 int ret = 0; 49 while( next() ) { 50 ret = dg( currentRow ); 51 if( ret != 0 ) break; 52 52 } 53 finish(); 54 return rows; 53 return ret; 55 54 } 56 55 57 56 /** 58 57 * Free all database resources used by a result set. 59 58 */ 60 abstract void finish (); 59 void finish (); 60 61 /** 62 * sets the fields array with ColInfo from individual dbi's 63 */ 64 void setFields (ColInfo[] flds) { 65 m_fields = flds.dup; 66 m_fieldCount = flds.length; 67 } 68 69 70 bool next() { 71 currentRow = fetchRow(); 72 if (currentRow is null) 73 return false; 74 return true; 75 } 76 77 private: 78 int m_fieldCount; 79 ColInfo[] m_fields; 80 81 Row[] rowbuf; 82 Row currentRow; 83 61 84 } branches/0.3-dev/dbi/Row.d
r59 r62 1 2 1 /** 3 2 * Authors: The D DBI project 4 *5 * Version: 0.2.56 3 * 7 4 * Copyright: BSD license … … 14 11 debug (UnitTest) private static import tango.io.Stdout; 15 12 } 16 private import dbi.DBIException ;13 private import dbi.DBIException, dbi.ColInfo; 17 14 18 15 /** 19 16 * Access to a single row in a result set. 20 *21 * Almost everything in this file is going to be deprecated and replaced soon. To22 * give your opinions on what should be done with it, go to the D DBI forums at23 * www.dsource.org/forums/viewtopic.php?t=1640. Whatever is decided will24 * take effect in version 0.3.0. Anything deprecated will be removed in version25 * 0.4.0.26 *27 * As a result, this file is no longer being updated with the exception of bug28 * fixes. It is highly recommended that even if you do not want to contribute29 * to the discussion on what to do to this file, you should follow the link to see30 * what the new version is likely to look like.31 17 */ 32 18 final class Row { 33 /**34 * Get a field's contents by index.35 *36 * Params:37 * idx = Field index.38 *39 * Examples:40 * ---41 * Row row = res.fetchRow();42 * writefln("first=%s, last=%s\n", row[0], row[1]);43 * ---44 *45 * Returns:46 * The field's contents.47 */48 char[] opIndex (int idx) {49 return get(idx);50 }51 19 52 /** 53 * Get a field's contents by field _name. 54 * 55 * Params: 56 * name = Field _name. 57 * 58 * Examples: 59 * --- 60 * Row row = res.fetchRow(); 61 * wriefln("first=%s, last=%s\n", row["first"], row["last"]); 62 * --- 63 * 64 * Returns: 65 * The field's contents. 66 */ 67 char[] opIndex (char[] name) { 68 return get(name); 20 this(int fieldCount) { 21 values.length = fieldCount; 69 22 } 70 23 … … 78 31 * The field's contents. 79 32 */ 80 char[] get(int idx) {81 return fieldValues[idx];33 void[] opIndex (int idx) { 34 return values[idx]; 82 35 } 83 36 84 /** 85 * Get a field's contents by field _name. 86 * 87 * Params: 88 * name = Field _name. 89 * 90 * Returns: 91 * The field's contents. 92 */ 93 char[] get (char[] name) { 94 return fieldValues[getFieldIndex(name)]; 37 void opIndexAssign (void[] value, int idx) { 38 values[idx] = value; 95 39 } 96 40 97 /** 98 * Get a field's index by field _name. 99 * 100 * Params: 101 * name = Field _name. 102 * 103 * Throws: 104 * DBIException if name is not a valid index. 105 * 106 * Returns: 107 * The field's index. 108 */ 109 int getFieldIndex (char[] name) { 110 for (int idx = 0; idx < fieldNames.length; idx++) { 111 if (fieldNames[idx] == name) { 112 return idx; 113 } 114 } 115 throw new DBIException("The name '" ~ name ~ "' is not a valid index."); 41 // opApply for fields ? 42 43 // getters 44 alias getUtf8 getString; 45 char[] getUtf8(int idx) { 46 return cast(char[])values[idx]; 116 47 } 117 48 118 /** 119 * Get the field type. 120 * 121 * Params: 122 * idx = Field index. 123 * 124 * Returns: 125 * The field's type. 126 */ 127 int getFieldType (int idx) { 128 return fieldTypes[idx]; 49 int getInt(int idx) { 50 return *cast(int*)values[idx]; 129 51 } 130 52 131 /** 132 * Get a field's SQL declaration. 133 * 134 * Params: 135 * idx = Field index. 136 * 137 * Returns: 138 * The field's SQL declaration. 139 */ 140 char[] getFieldDecl (int idx) { 141 return fieldDecls[idx]; 142 } 53 private: 54 void[][] values; 143 55 144 /**145 * Add a new field to this row.146 *147 * Params:148 * name = Name.149 * value = Value.150 * decl = SQL declaration, i.e. varchar(20), decimal(12,2), etc...151 * type = SQL _type.152 *153 * Todo:154 * SQL _type should be defined by the D DBI DBD interface spec, therefore155 * each DBD module will act exactly alike.156 */157 void addField (char[] name, char[] value, char[] decl, int type) {158 fieldNames ~= name;159 fieldValues ~= value.dup;160 fieldDecls ~= decl.dup;161 fieldTypes ~= type;162 }163 164 private:165 char[][] fieldNames;166 char[][] fieldValues;167 char[][] fieldDecls;168 int[] fieldTypes;169 56 } 170 171 unittest {172 version (Phobos) {173 void s1 (char[] s) {174 std.stdio.writefln("%s", s);175 }176 177 void s2 (char[] s) {178 std.stdio.writefln(" ...%s", s);179 }180 } else {181 void s1 (char[] s) {182 tango.io.Stdout.Stdout(s).newline();183 }184 185 void s2 (char[] s) {186 tango.io.Stdout.Stdout(" ..." ~ s).newline();187 }188 }189 190 s1("dbi.Row:");191 Row r1 = new Row();192 r1.addField("name", "John Doe", "text", 3);193 r1.addField("age", "23", "integer", 1);194 195 s2("get(int)");196 assert (r1.get(0) == "John Doe");197 198 s2("get(char[])");199 assert (r1.get("name") == "John Doe");200 201 s2("[int]");202 assert (r1[0] == "John Doe");203 204 s2("[char[]]");205 assert (r1["age"] == "23");206 207 s2("getFieldIndex");208 assert (r1.getFieldIndex("name") == 0);209 210 s2("getFieldType");211 assert (r1.getFieldType(0) == 3);212 213 s2("getFieldDecl");214 assert (r1.getFieldDecl(1) == "integer");215 }branches/0.3-dev/dbi/ib/imp.d
r59 r62 1 /**1 /** 2 2 * InterBase import library. 3 3 * branches/0.3-dev/dbi/mssql/MssqlDatabase.d
r59 r62 1 /**1 /** 2 2 * Authors: The D DBI project 3 3 * branches/0.3-dev/dbi/mssql/MssqlResult.d
r59 r62 1 /**1 /** 2 2 * Authors: The D DBI project 3 3 * … … 9 9 10 10 version (Phobos) { 11 private import std.string : toDString = toString, toCString = toStringz, locate = find; 11 private import std.string : toDString = toString, toCString = toStringz, 12 locate = find; 12 13 } else { 13 private import tango.stdc.stringz : toDString = fromUtf8z, toCString = toUtf8z; 14 debug(1) private import tango.io.Stdout; 15 private import tango.stdc.stringz : toDString = fromUtf8z, 16 toCString = toUtf8z; 14 17 private import tango.text.Util : locate; 15 18 private static import tango.text.convert.Float, tango.text.convert.Integer; 16 19 } 17 import dbi.DBIException, dbi.Result, dbi.Row ;20 import dbi.DBIException, dbi.Result, dbi.Row, dbi.ColInfo; 18 21 import dbi.mssql.imp, dbi.mssql.MssqlDate; 19 22 … … 25 28 */ 26 29 class MssqlResult : Result { 27 public: 28 this (CS_COMMAND* cmd) {30 31 public this (CS_COMMAND* cmd) { 29 32 this.cmd = cmd; 30 33 } … … 36 39 * A Row object with the queried information or null for an empty set. 37 40 */ 38 overrideRow fetchRow () {41 Row fetchRow () { 39 42 while (ct_results(cmd, &restype) == CS_SUCCEED) { 40 43 switch (restype) { … … 50 53 if (numFields < 0) { 51 54 setNumFields(); 52 setField s();55 setFieldInfo(); 53 56 } 54 57 // create new Row object, populate it, and return it 55 Row r = new Row( );58 Row r = new Row(numFields); 56 59 int count; 57 60 … … 59 62 numRows += count; 60 63 61 char[] value;62 char[] fieldname;63 64 64 for (int i = 0; i < numFields; ++i) { 65 fieldname = fields[i].name[0 .. locate(fields[i].name, '\0')];66 65 switch (fields[i].datatype) { 67 66 case CS_CHAR_TYPE: 68 value = strings[i][0 ..lengths[i]];67 r[i] = values[i][0..lengths[i]]; 69 68 break; 70 69 case CS_FLOAT_TYPE: 71 version (Phobos) { 72 value = toDString(floats[i]); 73 } else { 74 value = tango.text.convert.Float.toUtf8(floats[i]); 75 } 70 r[i] = values[i][0..double.sizeof]; 76 71 break; 72 /+ 77 73 case CS_DATETIME_TYPE: 78 74 MssqlDate date = new MssqlDate(dts[i]); … … 83 79 value = date.getString(); 84 80 break; 81 +/ 85 82 case CS_MONEY_TYPE: 86 /* fall through */ 83 r[i] = values[i][0..long.sizeof]; 84 double money = cast(double)(*cast(long*)r[i].ptr); 85 // r[i] = cast(void[])(money/10000); 86 break; 87 87 case CS_MONEY4_TYPE: 88 version (Phobos) { 89 value = toDString(cast(float)ints[i] / 10000); 90 } else { 91 value = tango.text.convert.Float.toUtf8(cast(float)ints[i] / 10000); 92 } 88 r[i] = values[i][0..int.sizeof]; 89 float money = cast(float)(*cast(int*)r[i].ptr); 90 // r[i] = cast(void[])(money/10000); 93 91 break; 94 92 default: 95 version (Phobos) { 96 value = toDString(ints[i]); 97 } else { 98 value = tango.text.convert.Integer.toUtf8(ints[i]); 99 } 93 r[i] = values[i][0..int.sizeof]; 100 94 break; 101 95 } 102 103 version (Phobos) {104 r.addField(fieldname, value, toDString(fields[i].datatype), fields[i].datatype);105 } else {106 r.addField(fieldname, value, tango.text.convert.Integer.toUtf8(fields[i].datatype), fields[i].datatype);107 }108 96 } 97 109 98 // we only want to return one row, so exit both while loops 110 99 return r; 111 100 } 112 default: 113 break; 114 } 101 default: 102 break; 115 103 } 116 return null;117 104 } 118 105 return null; 106 } 107 108 109 119 110 /** 120 111 * Free all database resources used by a result set. 121 112 */ 122 overridevoid finish () {113 void finish () { 123 114 /* TODO: */ 124 115 } 125 116 126 private:127 CS_COMMAND* cmd;128 CS_RETCODE restype;129 117 130 int numRows = -1; 131 int numFields = -1; 132 133 CS_DATAFMT[] fields; 134 char[][] strings; 135 CS_FLOAT[] floats; 136 CS_INT[] ints; 137 CS_DATETIME[] dts; 138 CS_DATETIME4[] dt4s; 139 int[] lengths; 140 short[] inds; 141 142 void setNumFields() { 118 private void setNumFields() { 143 119 // get field count 144 120 int _numFields; … … 147 123 148 124 // we can also set the length of the fields, strings, lengths, inds arrays 149 fields.length = lengths.length = inds.length= strings.length = floats.length = ints.length = dts.length = dt4s.length = numFields;125 fields.length = values.length = lengths.length = inds.length = numFields; 150 126 } 151 127 152 void setFields() { 153 int i; 128 private void setFieldInfo() { 154 129 130 ColInfo[] flds; 131 flds.length = numFields; 132 155 133 // for each field, set the field info in fields array, and bind field 156 134 // to other arrays 157 for (i = 0; i < numFields; ++i) {135 for (int i = 0; i < numFields; ++i) { 158 136 ct_describe(cmd, (i + 1), &fields[i]); 159 137 160 switch (fields[i].datatype) { 161 case CS_CHAR_TYPE: 162 if (strings[i].length != fields[i].maxlength) { 163 strings[i].length = fields[i].maxlength; 164 } 165 ct_bind(cmd, (i + 1), &fields[i], strings[i].ptr, &lengths[i], &inds[i]); 166 break; 167 case CS_FLOAT_TYPE: 168 ct_bind(cmd, (i + 1), &fields[i], &floats[i], &lengths[i], &inds[i]); 169 break; 170 case CS_DATETIME_TYPE: 171 ct_bind(cmd, (i + 1), &fields[i], &dts[i], &lengths[i], &inds[i]); 172 break; 173 case CS_DATETIME4_TYPE: 174 ct_bind(cmd, (i + 1), &fields[i], &dt4s[i], &lengths[i], &inds[i]); 175 break; 176 default: 177 ct_bind(cmd, (i + 1), &fields[i], &ints[i], &lengths[i], &inds[i]); 178 break; 138 // fill out ColInfo 139 ColInfo f = new ColInfo( 140 fields[i].name[0..fields[i].namelen], 141 // TODO: rest of params 142 "", 143 0, 144 0, 145 0, 146 0 147 ); 148 flds[i] = f; 149 150 // bind data to values array 151 if (values[i].length != fields[i].maxlength) { 152 values[i].length = fields[i].maxlength; 179 153 } 154 ct_bind(cmd, (i + 1), &fields[i], values[i].ptr, &lengths[i], 155 &inds[i]); 156 157 debug(1) { 158 Stdout ("name : ") (fields[i].name[0..fields[i].namelen]).newline; 159 Stdout ("namelen : ") (fields[i].namelen).newline; 160 Stdout ("datatype : ") (fields[i].datatype).newline; 161 Stdout ("format : ") (fields[i].format).newline; 162 Stdout ("maxlength: ") (fields[i].maxlength).newline; 163 Stdout ("scale : ") (fields[i].scale).newline; 164 Stdout ("precision: ") (fields[i].precision).newline; 165 Stdout ("status : ") (fields[i].status).newline; 166 Stdout ("count : ") (fields[i].count).newline; 167 Stdout ("usertype : ") (fields[i].usertype).newline; 168 Stdout ("locale : ") (fields[i].locale).newline; 169 Stdout.newline; 170 } 171 180 172 } 173 setFields(flds); 181 174 } 175 176 private { 177 CS_COMMAND* cmd; 178 CS_RETCODE restype; 179 180 int numRows = -1; 181 int numFields = -1; 182 183 CS_DATAFMT[] fields; 184 void[][] values; 185 int[] lengths; 186 short[] inds; 187 } 188 182 189 } branches/0.3-dev/dbi/mssql/imp.d
r59 r62 1 1 module dbi.mssql.imp; 2 2 3 /+ 3 4 version (Windows) { 4 5 pragma (lib, "libct.lib"); … … 12 13 pragma (msg, "You will need to manually link in the mSQL library."); 13 14 } 14 15 +/ 15 16 16 17 extern (C) {
