Skip to content

Commit 29b4168

Browse files
committed
More safe updates. Now builds the vibe tests.
1 parent 91752fc commit 29b4168

File tree

11 files changed

+215
-148
lines changed

11 files changed

+215
-148
lines changed

source/mysql/commands.d

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ struct ColumnSpecialization
5252
///ditto
5353
alias CSN = ColumnSpecialization;
5454

55+
@safe:
56+
5557
@("columnSpecial")
5658
debug(MYSQLN_TESTS)
5759
unittest
@@ -70,7 +72,7 @@ unittest
7072
immutable totalSize = 1000; // Deliberately not a multiple of chunkSize below
7173
auto alph = cast(const(ubyte)[]) "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
7274
auto data = alph.cycle.take(totalSize).array;
73-
cn.exec("INSERT INTO `columnSpecial` VALUES (\""~(cast(string)data)~"\")");
75+
cn.exec("INSERT INTO `columnSpecial` VALUES (\""~(cast(const(char)[])data)~"\")");
7476

7577
// Common stuff
7678
int chunkSize;
@@ -199,15 +201,15 @@ ulong exec(Connection conn, const(char[]) sql)
199201
}
200202
///ditto
201203
ulong exec(T...)(Connection conn, const(char[]) sql, T args)
202-
if(T.length > 0 && !is(T[0] == Variant[]))
204+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]))
203205
{
204206
auto prepared = conn.prepare(sql);
205207
prepared.setArgs(args);
206208
return exec(conn, prepared);
207209
}
208210
///ditto
209211
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
210-
ulong exec(Connection conn, const(char[]) sql, Variant[] args)
212+
ulong exec(Connection conn, const(char[]) sql, Variant[] args) @system
211213
{
212214
auto prepared = conn.prepare(sql);
213215
prepared.setArgs(args);
@@ -231,14 +233,14 @@ ulong exec(Connection conn, ref Prepared prepared)
231233
}
232234
///ditto
233235
ulong exec(T...)(Connection conn, ref Prepared prepared, T args)
234-
if(T.length > 0 && !is(T[0] == Variant[]))
236+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]))
235237
{
236238
prepared.setArgs(args);
237239
return exec(conn, prepared);
238240
}
239241
///ditto
240242
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
241-
ulong exec(Connection conn, ref Prepared prepared, Variant[] args)
243+
ulong exec(Connection conn, ref Prepared prepared, Variant[] args) @system
242244
{
243245
prepared.setArgs(args);
244246
return exec(conn, prepared);
@@ -341,15 +343,15 @@ ResultRange query(Connection conn, const(char[]) sql, ColumnSpecialization[] csa
341343
}
342344
///ditto
343345
ResultRange query(T...)(Connection conn, const(char[]) sql, T args)
344-
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
346+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
345347
{
346348
auto prepared = conn.prepare(sql);
347349
prepared.setArgs(args);
348350
return query(conn, prepared);
349351
}
350352
///ditto
351353
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
352-
ResultRange query(Connection conn, const(char[]) sql, Variant[] args)
354+
ResultRange query(Connection conn, const(char[]) sql, Variant[] args) @system
353355
{
354356
auto prepared = conn.prepare(sql);
355357
prepared.setArgs(args);
@@ -374,14 +376,14 @@ ResultRange query(Connection conn, ref Prepared prepared)
374376
}
375377
///ditto
376378
ResultRange query(T...)(Connection conn, ref Prepared prepared, T args)
377-
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
379+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
378380
{
379381
prepared.setArgs(args);
380382
return query(conn, prepared);
381383
}
382384
///ditto
383385
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
384-
ResultRange query(Connection conn, ref Prepared prepared, Variant[] args)
386+
ResultRange query(Connection conn, ref Prepared prepared, Variant[] args) @system
385387
{
386388
prepared.setArgs(args);
387389
return query(conn, prepared);
@@ -414,7 +416,7 @@ package ResultRange queryImpl(ColumnSpecialization[] csa,
414416
conn._rsh.addSpecializations(csa);
415417

416418
conn._headersPending = false;
417-
return ResultRange(SafeResultRange(conn, conn._rsh, conn._rsh.fieldNames));
419+
return ResultRange(conn, conn._rsh, conn._rsh.fieldNames);
418420
}
419421

420422
/++
@@ -487,7 +489,7 @@ Nullable!Row queryRow(Connection conn, const(char[]) sql, ColumnSpecialization[]
487489
}
488490
///ditto
489491
Nullable!Row queryRow(T...)(Connection conn, const(char[]) sql, T args)
490-
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
492+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
491493
{
492494
auto prepared = conn.prepare(sql);
493495
prepared.setArgs(args);
@@ -502,7 +504,7 @@ Nullable!Row queryRow(Connection conn, const(char[]) sql, MySQLVal[] args)
502504
}
503505
///ditto
504506
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
505-
Nullable!Row queryRow(Connection conn, const(char[]) sql, Variant[] args)
507+
Nullable!Row queryRow(Connection conn, const(char[]) sql, Variant[] args) @system
506508
{
507509
auto prepared = conn.prepare(sql);
508510
prepared.setArgs(args);
@@ -519,14 +521,14 @@ Nullable!Row queryRow(Connection conn, ref Prepared prepared)
519521
}
520522
///ditto
521523
Nullable!Row queryRow(T...)(Connection conn, ref Prepared prepared, T args)
522-
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
524+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
523525
{
524526
prepared.setArgs(args);
525527
return queryRow(conn, prepared);
526528
}
527529
///ditto
528530
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
529-
Nullable!Row queryRow(Connection conn, ref Prepared prepared, Variant[] args)
531+
Nullable!Row queryRow(Connection conn, ref Prepared prepared, Variant[] args) @system
530532
{
531533
prepared.setArgs(args);
532534
return queryRow(conn, prepared);
@@ -615,15 +617,17 @@ package void queryRowTupleImpl(T...)(Connection conn, ExecQueryImplInfo info, re
615617
ulong ra;
616618
enforce!MYXNoResultRecieved(execQueryImpl(conn, info, ra));
617619

618-
Row rr = conn.getNextRow();
620+
auto rr = conn.getNextRow();
619621
/+if (!rr._valid) // The result set was empty - not a crime.
620622
return;+/
621623
enforce!MYX(rr._values.length == args.length, "Result column count does not match the target tuple.");
622624
foreach (size_t i, dummy; args)
623625
{
624-
enforce!MYX(typeid(args[i]).toString() == rr._values[i].type.toString(),
626+
import taggedalgebraic.taggedalgebraic : get, hasType;
627+
enforce!MYX(rr._values[i].hasType!(T[i]),
625628
"Tuple "~to!string(i)~" type and column type are not compatible.");
626-
args[i] = rr._values[i].get!(typeof(args[i]));
629+
// use taggedalgebraic get to avoid extra calls.
630+
args[i] = get!(T[i])(rr._values[i]);
627631
}
628632
// If there were more rows, flush them away
629633
// Question: Should I check in purgeResult and throw if there were - it's very inefficient to
@@ -726,7 +730,7 @@ Nullable!MySQLVal queryValue(Connection conn, const(char[]) sql, ColumnSpecializ
726730
}
727731
///ditto
728732
Nullable!MySQLVal queryValue(T...)(Connection conn, const(char[]) sql, T args)
729-
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
733+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
730734
{
731735
auto prepared = conn.prepare(sql);
732736
prepared.setArgs(args);
@@ -741,7 +745,7 @@ Nullable!MySQLVal queryValue(Connection conn, const(char[]) sql, MySQLVal[] args
741745
}
742746
///ditto
743747
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
744-
Nullable!MySQLVal queryValue(Connection conn, const(char[]) sql, Variant[] args)
748+
Nullable!MySQLVal queryValue(Connection conn, const(char[]) sql, Variant[] args) @system
745749
{
746750
auto prepared = conn.prepare(sql);
747751
prepared.setArgs(args);
@@ -758,7 +762,7 @@ Nullable!MySQLVal queryValue(Connection conn, ref Prepared prepared)
758762
}
759763
///ditto
760764
Nullable!MySQLVal queryValue(T...)(Connection conn, ref Prepared prepared, T args)
761-
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
765+
if(T.length > 0 && !is(T[0] == Variant[]) && !is(T[0] == MySQLVal[]) && !is(T[0] == ColumnSpecialization) && !is(T[0] == ColumnSpecialization[]))
762766
{
763767
prepared.setArgs(args);
764768
return queryValue(conn, prepared);
@@ -771,7 +775,7 @@ Nullable!MySQLVal queryValue(Connection conn, ref Prepared prepared, MySQLVal[]
771775
}
772776
///ditto
773777
deprecated("Variant support is deprecated. Use MySQLVal[] instead of Variant[]")
774-
Nullable!MySQLVal queryValue(Connection conn, ref Prepared prepared, Variant[] args)
778+
Nullable!MySQLVal queryValue(Connection conn, ref Prepared prepared, Variant[] args) @system
775779
{
776780
prepared.setArgs(args);
777781
return queryValue(conn, prepared);
@@ -795,7 +799,7 @@ package Nullable!MySQLVal queryValueImpl(ColumnSpecialization[] csa, Connection
795799
return Nullable!MySQLVal();
796800
else
797801
{
798-
auto row = results.safe.front;
802+
auto row = results.front;
799803
results.close();
800804

801805
if(row.length == 0)
@@ -827,7 +831,7 @@ unittest
827831
// exec: const(char[]) sql
828832
assert(cn.exec("INSERT INTO `execOverloads` VALUES (1, \"aa\")") == 1);
829833
assert(cn.exec(prepareSQL, 2, "bb") == 1);
830-
assert(cn.exec(prepareSQL, [Variant(3), Variant("cc")]) == 1);
834+
assert(cn.exec(prepareSQL, [MySQLVal(3), MySQLVal("cc")]) == 1);
831835

832836
// exec: prepared sql
833837
auto prepared = cn.prepare(prepareSQL);
@@ -838,7 +842,7 @@ unittest
838842
assert(prepared.getArg(0) == 5);
839843
assert(prepared.getArg(1) == "ee");
840844

841-
assert(cn.exec(prepared, [Variant(6), Variant("ff")]) == 1);
845+
assert(cn.exec(prepared, [MySQLVal(6), MySQLVal("ff")]) == 1);
842846
assert(prepared.getArg(0) == 6);
843847
assert(prepared.getArg(1) == "ff");
844848

@@ -912,7 +916,7 @@ unittest
912916
assert(rows[0][0] == 2);
913917
assert(rows[0][1] == "bb");
914918

915-
rows = cn.query(prepareSQL, [Variant(3), Variant("cc")]).array;
919+
rows = cn.query(prepareSQL, [MySQLVal(3), MySQLVal("cc")]).array;
916920
assert(rows.length == 1);
917921
assert(rows[0].length == 2);
918922
assert(rows[0][0] == 3);
@@ -933,7 +937,7 @@ unittest
933937
assert(rows[0][0] == 2);
934938
assert(rows[0][1] == "bb");
935939

936-
rows = cn.query(prepared, [Variant(3), Variant("cc")]).array;
940+
rows = cn.query(prepared, [MySQLVal(3), MySQLVal("cc")]).array;
937941
assert(rows.length == 1);
938942
assert(rows[0].length == 2);
939943
assert(rows[0][0] == 3);
@@ -951,53 +955,55 @@ unittest
951955

952956
// Test queryRow
953957
{
954-
Nullable!Row row;
958+
Nullable!Row nrow;
959+
// avoid always saying nrow.get
960+
Row row() { return nrow.get; }
955961

956962
// String sql
957-
row = cn.queryRow("SELECT * FROM `queryOverloads` WHERE `i`=1 AND `s`=\"aa\"");
958-
assert(!row.isNull);
963+
nrow = cn.queryRow("SELECT * FROM `queryOverloads` WHERE `i`=1 AND `s`=\"aa\"");
964+
assert(!nrow.isNull);
959965
assert(row.length == 2);
960966
assert(row[0] == 1);
961967
assert(row[1] == "aa");
962968

963-
row = cn.queryRow(prepareSQL, 2, "bb");
964-
assert(!row.isNull);
969+
nrow = cn.queryRow(prepareSQL, 2, "bb");
970+
assert(!nrow.isNull);
965971
assert(row.length == 2);
966972
assert(row[0] == 2);
967973
assert(row[1] == "bb");
968974

969-
row = cn.queryRow(prepareSQL, [Variant(3), Variant("cc")]);
970-
assert(!row.isNull);
975+
nrow = cn.queryRow(prepareSQL, [MySQLVal(3), MySQLVal("cc")]);
976+
assert(!nrow.isNull);
971977
assert(row.length == 2);
972978
assert(row[0] == 3);
973979
assert(row[1] == "cc");
974980

975981
// Prepared sql
976982
auto prepared = cn.prepare(prepareSQL);
977983
prepared.setArgs(1, "aa");
978-
row = cn.queryRow(prepared);
979-
assert(!row.isNull);
984+
nrow = cn.queryRow(prepared);
985+
assert(!nrow.isNull);
980986
assert(row.length == 2);
981987
assert(row[0] == 1);
982988
assert(row[1] == "aa");
983989

984-
row = cn.queryRow(prepared, 2, "bb");
985-
assert(!row.isNull);
990+
nrow = cn.queryRow(prepared, 2, "bb");
991+
assert(!nrow.isNull);
986992
assert(row.length == 2);
987993
assert(row[0] == 2);
988994
assert(row[1] == "bb");
989995

990-
row = cn.queryRow(prepared, [Variant(3), Variant("cc")]);
991-
assert(!row.isNull);
996+
nrow = cn.queryRow(prepared, [MySQLVal(3), MySQLVal("cc")]);
997+
assert(!nrow.isNull);
992998
assert(row.length == 2);
993999
assert(row[0] == 3);
9941000
assert(row[1] == "cc");
9951001

9961002
// BCPrepared sql
9971003
auto bcPrepared = cn.prepareBackwardCompatImpl(prepareSQL);
9981004
bcPrepared.setArgs(1, "aa");
999-
row = cn.queryRow(bcPrepared);
1000-
assert(!row.isNull);
1005+
nrow = cn.queryRow(bcPrepared);
1006+
assert(!nrow.isNull);
10011007
assert(row.length == 2);
10021008
assert(row[0] == 1);
10031009
assert(row[1] == "aa");
@@ -1030,48 +1036,48 @@ unittest
10301036

10311037
// Test queryValue
10321038
{
1033-
Nullable!Variant value;
1039+
Nullable!MySQLVal value;
10341040

10351041
// String sql
10361042
value = cn.queryValue("SELECT * FROM `queryOverloads` WHERE `i`=1 AND `s`=\"aa\"");
10371043
assert(!value.isNull);
1038-
assert(value.get.type != typeid(typeof(null)));
1044+
assert(value.get.kind != MySQLVal.Kind.Null);
10391045
assert(value.get == 1);
10401046

10411047
value = cn.queryValue(prepareSQL, 2, "bb");
10421048
assert(!value.isNull);
1043-
assert(value.get.type != typeid(typeof(null)));
1049+
assert(value.get.kind != MySQLVal.Kind.Null);
10441050
assert(value.get == 2);
10451051

1046-
value = cn.queryValue(prepareSQL, [Variant(3), Variant("cc")]);
1052+
value = cn.queryValue(prepareSQL, [MySQLVal(3), MySQLVal("cc")]);
10471053
assert(!value.isNull);
1048-
assert(value.get.type != typeid(typeof(null)));
1054+
assert(value.get.kind != MySQLVal.Kind.Null);
10491055
assert(value.get == 3);
10501056

10511057
// Prepared sql
10521058
auto prepared = cn.prepare(prepareSQL);
10531059
prepared.setArgs(1, "aa");
10541060
value = cn.queryValue(prepared);
10551061
assert(!value.isNull);
1056-
assert(value.get.type != typeid(typeof(null)));
1062+
assert(value.get.kind != MySQLVal.Kind.Null);
10571063
assert(value.get == 1);
10581064

10591065
value = cn.queryValue(prepared, 2, "bb");
10601066
assert(!value.isNull);
1061-
assert(value.get.type != typeid(typeof(null)));
1067+
assert(value.get.kind != MySQLVal.Kind.Null);
10621068
assert(value.get == 2);
10631069

1064-
value = cn.queryValue(prepared, [Variant(3), Variant("cc")]);
1070+
value = cn.queryValue(prepared, [MySQLVal(3), MySQLVal("cc")]);
10651071
assert(!value.isNull);
1066-
assert(value.get.type != typeid(typeof(null)));
1072+
assert(value.get.kind != MySQLVal.Kind.Null);
10671073
assert(value.get == 3);
10681074

10691075
// BCPrepared sql
10701076
auto bcPrepared = cn.prepareBackwardCompatImpl(prepareSQL);
10711077
bcPrepared.setArgs(1, "aa");
10721078
value = cn.queryValue(bcPrepared);
10731079
assert(!value.isNull);
1074-
assert(value.get.type != typeid(typeof(null)));
1080+
assert(value.get.kind != MySQLVal.Kind.Null);
10751081
assert(value.get == 1);
10761082
}
10771083
}

source/mysql/connection.d

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import mysql.protocol.packets;
1818
import mysql.protocol.sockets;
1919
import mysql.result;
2020
import mysql.types;
21+
22+
@safe:
23+
2124
debug(MYSQLN_TESTS)
2225
{
2326
import mysql.test.common;

source/mysql/escape.d

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,9 @@ struct MysqlEscape ( Input )
4545
{
4646
Input input;
4747

48-
const void toString ( scope void delegate(const(char)[]) sink )
48+
const void toString ( scope void delegate(const(char)[]) @safe sink )
4949
{
50-
struct SinkOutputRange
51-
{
52-
void put ( const(char)[] t ) { sink(t); }
53-
}
54-
55-
SinkOutputRange r;
56-
mysql_escape(input, r);
50+
mysql_escape(input, sink);
5751
}
5852
}
5953

0 commit comments

Comments
 (0)