This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Add datetime read span path for netcore #31044
Merged
Merged
Changes from 16 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
09ce37f
add datetime read span path for netcore
Wraith2 6358d2a
address feedback
Wraith2 b1c7cfe
correct filename case in project
Wraith2 9514fc7
remove netcore files
Wraith2 221498f
add netcore files with correct case
Wraith2 2bec7ea
fix other case in project
Wraith2 2f78a0b
remove netcore #ifdefs
Wraith2 0fb752f
Merge remote-tracking branch 'origin/master' into sqldatespan2
Wraith2 c0b5e0b
Merge branch 'master' into sqldatespan2
Wraith2 75fb446
change out variable to c#7 dicard
Wraith2 275cecd
address feedback
Wraith2 173bbe7
change to implicit span where possible
Wraith2 1d9b934
space
Wraith2 1277c2d
update stackalloc for security concerns
Wraith2 2e1d6f6
remove partial
Wraith2 18789a8
remove length parameters from spanified functions
Wraith2 8a2c3aa
fixed buffer copy to correctly use offset
Wraith2 8618058
makes type declaration of copy target explicit
Wraith2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1027,90 +1027,47 @@ internal void SetToString(string value) | |
_isNull = false; | ||
} | ||
|
||
internal void SetToDate(byte[] bytes) | ||
internal void SetToDate(ReadOnlySpan<byte> bytes) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
_type = StorageType.Date; | ||
_value._int32 = GetDateFromByteArray(bytes, 0); | ||
_value._int32 = GetDateFromByteArray(bytes); | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToDate(DateTime date) | ||
internal void SetToTime(ReadOnlySpan<byte> bytes, byte scale) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
_type = StorageType.Date; | ||
_value._int32 = date.Subtract(DateTime.MinValue).Days; | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToTime(byte[] bytes, int length, byte scale) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
_type = StorageType.Time; | ||
FillInTimeInfo(ref _value._timeInfo, bytes, length, scale); | ||
FillInTimeInfo(ref _value._timeInfo, bytes, scale); | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToTime(TimeSpan timeSpan, byte scale) | ||
internal void SetToDateTime2(ReadOnlySpan<byte> bytes, byte scale) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It means that it's using the data layout for an sql type SQLDATETIME2, which represents a datetime2 and I agree that it's a silly name but that's what it's called. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ugh. Ok, thanks. |
||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
_type = StorageType.Time; | ||
_value._timeInfo.ticks = timeSpan.Ticks; | ||
_value._timeInfo.scale = scale; | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToDateTime2(byte[] bytes, int length, byte scale) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
int length = bytes.Length; | ||
_type = StorageType.DateTime2; | ||
FillInTimeInfo(ref _value._dateTime2Info.timeInfo, bytes, length - 3, scale); // remaining 3 bytes is for date | ||
_value._dateTime2Info.date = GetDateFromByteArray(bytes, length - 3); // 3 bytes for date | ||
FillInTimeInfo(ref _value._dateTime2Info.timeInfo, bytes.Slice(0, length - 3), scale); // remaining 3 bytes is for date | ||
_value._dateTime2Info.date = GetDateFromByteArray(bytes.Slice(length - 3)); // 3 bytes for date | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToDateTime2(DateTime dateTime, byte scale) | ||
internal void SetToDateTimeOffset(ReadOnlySpan<byte> bytes, byte scale) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
_type = StorageType.DateTime2; | ||
_value._dateTime2Info.timeInfo.ticks = dateTime.TimeOfDay.Ticks; | ||
_value._dateTime2Info.timeInfo.scale = scale; | ||
_value._dateTime2Info.date = dateTime.Subtract(DateTime.MinValue).Days; | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToDateTimeOffset(byte[] bytes, int length, byte scale) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
int length = bytes.Length; | ||
_type = StorageType.DateTimeOffset; | ||
FillInTimeInfo(ref _value._dateTimeOffsetInfo.dateTime2Info.timeInfo, bytes, length - 5, scale); // remaining 5 bytes are for date and offset | ||
_value._dateTimeOffsetInfo.dateTime2Info.date = GetDateFromByteArray(bytes, length - 5); // 3 bytes for date | ||
FillInTimeInfo(ref _value._dateTimeOffsetInfo.dateTime2Info.timeInfo, bytes.Slice(0, length - 5), scale); // remaining 5 bytes are for date and offset | ||
_value._dateTimeOffsetInfo.dateTime2Info.date = GetDateFromByteArray(bytes.Slice(length - 5)); // 3 bytes for date | ||
_value._dateTimeOffsetInfo.offset = (short)(bytes[length - 2] + (bytes[length - 1] << 8)); // 2 bytes for offset (Int16) | ||
_isNull = false; | ||
} | ||
|
||
internal void SetToDateTimeOffset(DateTimeOffset dateTimeOffset, byte scale) | ||
{ | ||
Debug.Assert(IsEmpty, "setting value a second time?"); | ||
|
||
_type = StorageType.DateTimeOffset; | ||
DateTime utcDateTime = dateTimeOffset.UtcDateTime; // timeInfo stores the utc datetime of a datatimeoffset | ||
_value._dateTimeOffsetInfo.dateTime2Info.timeInfo.ticks = utcDateTime.TimeOfDay.Ticks; | ||
_value._dateTimeOffsetInfo.dateTime2Info.timeInfo.scale = scale; | ||
_value._dateTimeOffsetInfo.dateTime2Info.date = utcDateTime.Subtract(DateTime.MinValue).Days; | ||
_value._dateTimeOffsetInfo.offset = (short)dateTimeOffset.Offset.TotalMinutes; | ||
_isNull = false; | ||
} | ||
|
||
private static void FillInTimeInfo(ref TimeInfo timeInfo, byte[] timeBytes, int length, byte scale) | ||
private static void FillInTimeInfo(ref TimeInfo timeInfo, ReadOnlySpan<byte> timeBytes, byte scale) | ||
{ | ||
int length = timeBytes.Length; | ||
Debug.Assert(3 <= length && length <= 5, "invalid data length for timeInfo: " + length); | ||
Debug.Assert(0 <= scale && scale <= 7, "invalid scale: " + scale); | ||
|
||
|
@@ -1127,9 +1084,10 @@ private static void FillInTimeInfo(ref TimeInfo timeInfo, byte[] timeBytes, int | |
timeInfo.scale = scale; | ||
} | ||
|
||
private static int GetDateFromByteArray(byte[] buf, int offset) | ||
private static int GetDateFromByteArray(ReadOnlySpan<byte> buf) | ||
{ | ||
return buf[offset] + (buf[offset + 1] << 8) + (buf[offset + 2] << 16); | ||
byte thirdByte = buf[2]; // reordered to optimize JIT generated bounds checks to a single instance, review generated asm before changing | ||
return buf[0] + (buf[1] << 8) + (thirdByte << 16); | ||
} | ||
|
||
private void ThrowIfNull() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@safern, should this be under the ItemGroup that is just
Condition="'$(IsPartialFacadeAssembly)' != 'true'
? Why do we need to avoid adding the reference to System.Memory for AnyOS?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I missed the notification to this question.
We don't need to avoid the reference, but it doesn't make sense to add the reference for AnyOS as we're not exposing any public API that uses
System.Memory
and when AnyOS == true we generate a platform not supported exception, so basically we would just be bringing a non-used dependency to the turd assembly.corefx/src/System.Data.SqlClient/src/System.Data.SqlClient.csproj
Line 8 in f6bb008