1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| USING System;
USING System.Data.SqlTypes;
USING Microsoft.SqlServer.Server;
USING System.Collections;
[assembly: CLSCompliant(TRUE)]
namespace Range {
public static partial class UserDefinedFunctions {
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = TRUE, SystemDataAccess = SystemDataAccessKind.None, IsPrecise = TRUE, FillRowMethodName ="FillRow", TableDefinition ="n bigint")]
public static IEnumerable Range(SqlInt64 START, SqlInt64 END, SqlInt64 incr) {
RETURN NEW Ranger(START.Value, END.Value, incr.Value);
}
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = TRUE, SystemDataAccess = SystemDataAccessKind.None, IsPrecise = TRUE, FillRowMethodName ="FillRowF", TableDefinition ="n float")]
public static IEnumerable RangeF(SqlDouble START, SqlDouble END, SqlDouble incr) {
RETURN NEW RangerF(START.Value, END.Value, incr.Value);
}
public static void FillRow(object ROW, OUT SqlInt64 n) {
n = NEW SqlInt64((long)ROW);
}
public static void FillRowF(object ROW, OUT SqlDouble n) {
n = NEW SqlDouble((DOUBLE)ROW);
}
}
internal class Ranger : IEnumerable {
Int64 _start, _end, _incr;
public Ranger(Int64 START, Int64 END, Int64 incr) {
_start = START; _end = END; _incr = incr;
}
public IEnumerator GetEnumerator() {
RETURN NEW RangerEnum(_start, _end, _incr);
}
}
internal class RangerF : IEnumerable {
DOUBLE _start, _end, _incr;
public RangerF(DOUBLE START, DOUBLE END, DOUBLE incr) {
_start = START; _end = END; _incr = incr;
}
public IEnumerator GetEnumerator() {
RETURN NEW RangerFEnum(_start, _end, _incr);
}
}
internal class RangerEnum : IEnumerator {
Int64 _cur, _start, _end, _incr;
bool hasFetched = FALSE;
public RangerEnum(Int64 START, Int64 END, Int64 incr) {
_start = _cur = START; _end = END; _incr = incr;
IF ((_start < _end ^ _incr > 0) || _incr == 0)
throw NEW ArgumentException("Will never reach end!");
}
public long CURRENT {
GET { hasFetched = TRUE; RETURN _cur; }
}
object IEnumerator.Current {
GET { hasFetched = TRUE; RETURN _cur; }
}
public bool MoveNext() {
IF (hasFetched) _cur += _incr;
RETURN (_cur > _end ^ _incr > 0);
}
public void Reset() {
_cur = _start; hasFetched = FALSE;
}
}
internal class RangerFEnum : IEnumerator {
DOUBLE _cur, _start, _end, _incr;
bool hasFetched = FALSE;
public RangerFEnum(DOUBLE START, DOUBLE END, DOUBLE incr) {
_start = _cur = START; _end = END; _incr = incr;
IF ((_start < _end ^ _incr > 0) || _incr == 0)
throw NEW ArgumentException("Will never reach end!");
}
public DOUBLE CURRENT {
GET { hasFetched = TRUE; RETURN _cur; }
}
object IEnumerator.Current {
GET { hasFetched = TRUE; RETURN _cur; }
}
public bool MoveNext() {
IF (hasFetched) _cur += _incr;
RETURN (_cur > _end ^ _incr > 0);
}
public void Reset() {
_cur = _start; hasFetched = FALSE;
}
}
} |