[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-04 Thread William Drago
Jean,

Thanks for the reply. I understand this very well, and I 
have read this page many times over the past few years:

http://www.sqlite.org/datatype3.html


My argument is that regardless of a column's type or type 
affinity, a method called ReadBytes() should read the bytes 
as stored in the database and let the programmer figure out 
what to do with them.

The latest doc available here (very last link on page):

http://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki

shows no methods for reading BLOBs. There are methods like 
GetString, GetFloat, GetDouble, etc., but nothing called 
GetBlob.

GetBytes is describes as follows:

SQLiteDataReader.GetBytes Method
Retrieves a column as an array of bytes (blob)

public override long GetBytes(
int i,
long fieldOffset,
byte[] buffer,
int bufferoffset,
int length
);

Parameters

i
The index of the column to retrieve

fieldOffset
The zero-based index of where to begin reading the data

buffer
The buffer to write the bytes into

bufferoffset
The zero-based index of where to begin writing into the array

length
The number of bytes to retrieve

Return Value
The actual number of bytes written into the array

That implies that it will read the bytes of any column 
regardless of type. Why on Earth would a method called 
GetBytes restrict itself to only those columns with blob 
affinity? It doesn't make any sense. It should be called 
GetBlob to match the naming convention of all the other 
Getxxx methods.

I realize this is an ADO.NET thing and I'm not casting blame 
on the System.Data.SQLite devs. The spec is the spec.

Sorry for the rant...

Have a good weekend, and thanks again for spending the time 
on this. I have learned more from the people on the list 
than I ever imagined.

Regards,
-Bill

On 7/3/2015 1:51 PM, Jean Chevalier wrote:
> In SQLite, every value you store is stored alongside its type. This is unlike 
> other databases where the column determines the type and every value stored 
> against it share it. In SQLite you could have a table in which all value 
> types as stored contradict all column types as declared, if you so craft it 
> (except integer primary key). As for a column declared BLOB, it results in an 
> affinity of NONE meaning "perform no implicit conversions" (as long as 
> lossless and reversible), it doesn't mean "affinity binary" because there is 
> no such thing as something more generic than binary that should implicitly be 
> cast to binary upon storing it. So a blob-declared column would not try and 
> implicitly convert, but it will still store exactly what you put in, 
> including its type, inferred from the way in which you did the assignment, 
> e.g., for set c = '1' it will store {text-1} for integer it will store 
> {integer-of-1-} (a special case), for x'01' it will store {blob-01}, 
> and so on. Th!
>   is lower
>   case 'blob' is the most generic case (your 'bytes') but to obtain that one 
> must cast() to a blob which means "strip from what I'm giving you any 
> indication that it may be a text, or an integer, or a real, as it is really 
> neither". Think of blob not as a type ('binary') but the absence of types. 
> You can further apply a check constraint to the column to ensure that no 
> value stored will be stored along with a tag meaning "I'm of a certain kind". 
> This check(typeof(c)='blob') will ensure the data you put in will be 'naked' 
> so to speak, and when the data you put in is naked, SQLite can only store it 
> as bytes, and by default return it as bytes. So you can see how it differs, 
> blob as column type meaning 'suggest no type' or 'add no type' and blob as 
> value type meaning 'a value with no type tag attached' or 'convey no type'. 
> They're complementary. Think of the two together as "none given - none taken" 
> (or 'none added'). Naturally the constraint will not let you set c = '1' 
> because '!
>   1' implie
>   s text by way of the quotes, same for Int (and how would it know if you 
> meant a one-byte int, or two, or four?), and I think that's what you want in 
> your application, but it will let you assign something in the x'' notation, 
> or a cast() expression. So a check constraint makes the column more 
> 'demanding' so to speak, type-wise, stricter, and closer to what you observe 
> in other databases. Just remember to tweak the check constraint to allow 
> nulls for nullable columns. After which, we'd expect that if no type marker 
> was carried in, none will come out upon querying it, unless you have some 
> other layer wrapped around it such as some ODBC driver assuming that it's its 
> duty to further cast a column to a target type based on the column's declared 
> type. But this is because some wrapper drivers assume the user will try and 
> use SQLite as he uses most other databases, or because the driver cannot 
> support exposing a series of column values of varying types. A native SQLite 
> driver (one b!
>   uilt in a
>   ccordance to how 

[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-03 Thread Jean Chevalier
In SQLite, every value you store is stored alongside its type. This is unlike 
other databases where the column determines the type and every value stored 
against it share it. In SQLite you could have a table in which all value types 
as stored contradict all column types as declared, if you so craft it (except 
integer primary key). As for a column declared BLOB, it results in an affinity 
of NONE meaning "perform no implicit conversions" (as long as lossless and 
reversible), it doesn't mean "affinity binary" because there is no such thing 
as something more generic than binary that should implicitly be cast to binary 
upon storing it. So a blob-declared column would not try and implicitly 
convert, but it will still store exactly what you put in, including its type, 
inferred from the way in which you did the assignment, e.g., for set c = '1' it 
will store {text-1} for integer it will store {integer-of-1-} (a 
special case), for x'01' it will store {blob-01}, and so on. This lower case 
'blob' is the most generic case (your 'bytes') but to obtain that one must 
cast() to a blob which means "strip from what I'm giving you any indication 
that it may be a text, or an integer, or a real, as it is really neither". 
Think of blob not as a type ('binary') but the absence of types. You can 
further apply a check constraint to the column to ensure that no value stored 
will be stored along with a tag meaning "I'm of a certain kind". This 
check(typeof(c)='blob') will ensure the data you put in will be 'naked' so to 
speak, and when the data you put in is naked, SQLite can only store it as 
bytes, and by default return it as bytes. So you can see how it differs, blob 
as column type meaning 'suggest no type' or 'add no type' and blob as value 
type meaning 'a value with no type tag attached' or 'convey no type'. They're 
complementary. Think of the two together as "none given - none taken" (or 'none 
added'). Naturally the constraint will not let you set c = '1' because '1' 
implies text by way of the quotes, same for Int (and how would it know if you 
meant a one-byte int, or two, or four?), and I think that's what you want in 
your application, but it will let you assign something in the x'' notation, or 
a cast() expression. So a check constraint makes the column more 'demanding' so 
to speak, type-wise, stricter, and closer to what you observe in other 
databases. Just remember to tweak the check constraint to allow nulls for 
nullable columns. After which, we'd expect that if no type marker was carried 
in, none will come out upon querying it, unless you have some other layer 
wrapped around it such as some ODBC driver assuming that it's its duty to 
further cast a column to a target type based on the column's declared type. But 
this is because some wrapper drivers assume the user will try and use SQLite as 
he uses most other databases, or because the driver cannot support exposing a 
series of column values of varying types. A native SQLite driver (one built in 
accordance to how SQLite really works) shouldn't take this freedom.


You wrote:
>
> My assumption was that GetBytes() could be used to read
> the bytes of any column regardless of type. What difference
> should column type or affinity make if I'm asking for bytes?
> If I'm using GetBytes() on a column with REAL affinity,
> it should put 8 bytes in the read buffer, but it doesn't.
> If I send text to a BLOB column it's typeof() changes to
> TEXT which confuses GetBytes(). I think this is pretty silly
> because bytes are bytes, right? Why bother verifying type
> when the method name already tells you what you are getting
> and bytes can be obtained from any data type?
> (Rhetorical questions, but feel free to respond anyway.)
>


[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread Drago, William @ CSG - NARDA-MITEQ
Lots of good replies. My problem is solved, thank you.

My assumption was that GetBytes() could be used to read the bytes of any column 
regardless of type. What difference should column type or affinity make if I'm 
asking for bytes? If I'm using GetBytes() on a column with REAL affinity, it 
should put 8 bytes in the read buffer, but it doesn't. If I send text to a BLOB 
column it's typeof() changes to TEXT which confuses GetBytes(). I think this is 
pretty silly because bytes are bytes, right? Why bother verifying type when the 
method name already tells you what you are getting and bytes can be obtained 
from any data type? (Rhetorical questions, but feel free to respond anyway.)

Anyway, the problem is solved. Thank you all.

( cast('x y z' as blob) ) is especially convenient. Thank you for that 
excellent suggestion, Jean (and thanks for the Stack Overflow link, that helped 
too).

And thanks to R. Smith for posting the informative examples that also helped me 
understand what was happening.

--
Bill Drago
Staff Engineer
L3 Narda-MITEQ
435 Moreland Road
Hauppauge, NY 11788
631-272-5947 / William.Drago at L-3COM.com


> -Original Message-
> From: sqlite-users-bounces at mailinglists.sqlite.org [mailto:sqlite-
> users-bounces at mailinglists.sqlite.org] On Behalf Of Jean Chevalier
> Sent: Thursday, July 02, 2015 1:40 PM
> To: sqlite-users at mailinglists.sqlite.org
> Subject: Re: [sqlite] Reader.GetBytes() - when is a byte not a byte?
>
> It's not mandatory to use x'' notation to insert into a blob, when
> one can use cast.
>
> The following should return blob content correctly without explicitly
> lying it down as Hex:
>
> sqlite> create table T (c blob check(typeof(c) = 'blob'));
>
> sqlite> insert into T values ( cast('x y z' as blob) );
>
> sqlite> select c from T;
>
> x y z
>
> Please check whether your calling program consumes the above as text or
> blob, I'd expect blob.
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
CONFIDENTIALITY, EXPORT CONTROL AND DISCLAIMER NOTE:This e-mail and any 
attachments are solely for the use of the addressee and may contain information 
that is privileged or confidential. Any disclosure, use or distribution of the 
information contained herein is prohibited. In the event this e-mail contains 
technical data within the definition of the International Traffic in Arms 
Regulations or Export Administration Regulations, it is subject to the export 
control laws of the U.S.Government. The recipient should check this e-mail and 
any attachments for the presence of viruses as L-3 does not accept any 
liability associated with the transmission of this e-mail. If you have received 
this communication in error, please notify the sender by reply e-mail and 
immediately delete this message and any attachments.


[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread Jean Chevalier
It's not mandatory to use x'' notation to insert into a blob, when one can 
use cast.

The following should return blob content correctly without explicitly lying it 
down as Hex:

sqlite> create table T (c blob check(typeof(c) = 'blob'));

sqlite> insert into T values ( cast('x y z' as blob) );

sqlite> select c from T;

x y z

Please check whether your calling program consumes the above as text or blob, 
I'd expect blob.


[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread R.Smith


On 2015-07-02 03:24 PM, R.Smith wrote:
> That exception is only thrown if the source column is not a BLOB (as 
> far as I can tell).
>
> You specify the column Type (or type affinity) as BLOB but then you 
> store a non-BLOB TEXT value in it ('"blue" "red" "orange" "yellow"' 
> <-- Not a BLOB)
> SQLite will store this as TEXT, not BLOB.
>
> A BLOB starts with an x followed by a string of Hex, like in your 
> other inserted values such as:  X'FFFEFDFCFBFAF9F8F7F6'
>
> The BLOB for your '"blue" "red" "orange" "yellow"' string will look 
> like this:
> x'22626C75652220227265642220226F72616E676522202279656C6C6F7722'
>
> Insert that and getBytes() will work just fine.
>
> PS: This solution presupposes the enforcement of BLOB-ness, I'm not 
> exactly sure if this is the intention from SQLite or indeed a bug / 
> undesired side-effect.
>

To be sure, here is a script to point out the difference:

CREATE TABLE myTable (
myText Text,
myTextArray BLOB, --Text
myBool Boolean,
myBoolArray BLOB, --Boolean
myUInt8 UInt8,
myUInt8Array BLOB, --UInt8
myUInt16 UInt16,
myUInt16Array BLOB, --UInt16
myInt16 Int16,
myInt16Array BLOB, --Int16
myInt32 Int32,
myInt32Array BLOB, --Int32
myInt64 Int64,
myInt64Array BLOB, --Int64
myReal32 Real32,
myReal32Array BLOB, --Real32
myReal64 Real64,
myReal64Array BLOB --Real64
);

INSERT INTO "myTable" VALUES
('This is text','"blue" "red" "orange" "yellow"',
  0,X'00010001',
  255,X'FFFEFDFCFBFAF9F8F7F6',
  65535,X'FEFFFDFFFCFFFBFFFAFFFAFFFBFFFCFFFDFF',
  32767,X'FF7F01800100020003000400050006000700',
  2147483647,X'FF7F00800100',
  
9223372036854775807,X'FF7F00800100',
  
3.40282346638528897567e+38,X'7F7F70443901803F004040408040A040C040E040',
  
1.79769313486231063271e+308,X'66E62440AE47E17A14AEF33F33B323C0007862A441A7C043'),

('This is 
text2',x'22626C75652220227265642220226F72616E676522202279656C6C6F7722',
  0,X'00010001',
  255,X'FFFEFDFCFBFAF9F8F7F6',
  65535,X'FEFFFDFFFCFFFBFFFAFFFAFFFBFFFCFFFDFF',
  32767,X'FF7F01800100020003000400050006000700',
  2147483647,X'FF7F00800100',
  
9223372036854775807,X'FF7F00800100',
  
3.40282346638528897567e+38,X'7F7F70443901803F004040408040A040C040E040',
  
1.79769313486231063271e+308,X'66E62440AE47E17A14AEF33F33B323C0007862A441A7C043');

// Query showing only [BLOB] placeholders for all actual BLOBs
SELECT typeof(myTextArray), myText, myTextArray, myBool, myBoolArray, 
myUInt8, myUInt8Array FROM myTable;

   -- typeof(m- | |||   | |
   -- yTextArr- | ||| myBoolAr- 
| | myUInt8A-
   -- ay)   | myText  | myTextArray| 
myBool | ray   | myUInt8 | rray
   -- - | --- | -- | 
-- | - | --- | -
   -- text  | This is text| "blue" "red" "orange" "yellow" |
0   | [Blob]|   255   | [Blob]
   -- blob  | This is text2   | [Blob] |
0   | [Blob]|   255   | [Blob]


// Same query showing full BLOB values(this program uses getBytes() 
internally when an actual BLOB is encountered)
SELECT typeof(myTextArray), myText, myTextArray, myBool, myBoolArray, 
myUInt8, myUInt8Array FROM myTable;

   -- typeof(m- | | ||  | |
   -- yTextArr- | | ||  | |
   -- ay)   | myText  | 
myTextArray  | 
myBool | myBoolArray  | myUInt8 | myUInt8Array
   -- - | --- | 
 | 
-- |  | --- | 
   -- text  | This is text| "blue" "red" "orange" 
"yellow"   |0   | 0x00010001 |   
255   | 0xFFFEFDFCFBFAF9F8F7F6
   -- blob  | This is text2   | 
0x22626C75652220227265642220226F72616E676522202279656C6C6F7722 |0   
| 0x00010001   |   255   | 0xFFFEFDFCFBFAF9F8F7F6

   -- 



>
>
> On 2015-07-02 01:47 PM, William Drago wrote:
>> All,
>>
>> Below is a .dump of the database I'm working with. I can use 
>> GetBytes() successfully on all the BLOB columns except myTextArray. 
>> On that column I get a System.InvalidCastException error. Can anyone 
>> tell me why? Thanks.
>>
>> -Bill
>>
>>
>> ---.dump file---
>>
>> PRAGMA foreign_keys=OFF;
>> BEGIN TRANSACTION;
>> CREATE TABLE myTable (
>>
>> myText Text,
>>
>> myTextArray BLOB, --Text
>>
>> myBool Boolean,
>>
>> myBoolArray BLOB, --Boolean
>>
>> myUInt8 UInt8,
>>
>> myUInt8Array BLOB, --UInt8
>>
>> myUInt16 UInt16,
>>
>> myUInt16Array BLOB, --UInt16
>>

[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread R.Smith
That exception is only thrown if the source column is not a BLOB (as far 
as I can tell).

You specify the column Type (or type affinity) as BLOB but then you 
store a non-BLOB TEXT value in it ('"blue" "red" "orange" "yellow"' <-- 
Not a BLOB)
SQLite will store this as TEXT, not BLOB.

A BLOB starts with an x followed by a string of Hex, like in your other 
inserted values such as:  X'FFFEFDFCFBFAF9F8F7F6'

The BLOB for your '"blue" "red" "orange" "yellow"' string will look like 
this:
x'22626C75652220227265642220226F72616E676522202279656C6C6F7722'

Insert that and getBytes() will work just fine.

PS: This solution presupposes the enforcement of BLOB-ness, I'm not 
exactly sure if this is the intention from SQLite or indeed a bug / 
undesired side-effect.



On 2015-07-02 01:47 PM, William Drago wrote:
> All,
>
> Below is a .dump of the database I'm working with. I can use 
> GetBytes() successfully on all the BLOB columns except myTextArray. On 
> that column I get a System.InvalidCastException error. Can anyone tell 
> me why? Thanks.
>
> -Bill
>
>
> ---.dump file---
>
> PRAGMA foreign_keys=OFF;
> BEGIN TRANSACTION;
> CREATE TABLE myTable (
>
> myText Text,
>
> myTextArray BLOB, --Text
>
> myBool Boolean,
>
> myBoolArray BLOB, --Boolean
>
> myUInt8 UInt8,
>
> myUInt8Array BLOB, --UInt8
>
> myUInt16 UInt16,
>
> myUInt16Array BLOB, --UInt16
>
> myInt16 Int16,
>
> myInt16Array BLOB, --Int16
>
> myInt32 Int32,
>
> myInt32Array BLOB, --Int32
>
> myInt64 Int64,
>
> myInt64Array BLOB, --Int64
>
> myReal32 Real32,
>
> myReal32Array BLOB, --Real32
>
> myReal64 Real64,
>
> myReal64Array BLOB --Real64
>
> );
> INSERT INTO "myTable" VALUES('This is text','"blue" "red" "orange" 
> "yellow"',0,X'00010001',255,X'FFFEFDFCFBFAF9F8F7F6',65535,X'FEFFFDFFFCFFFBFFFAFFFAFFFBFFFCFFFDFF',32767,X'FF7F01800100020003000400050006000700',2147483647,X'FF7F00800100',9223372036854775807,X'FF7F00800100',3.40282346638528897567e+38,X'7F7F70443901803F004040408040A040C040E040',1.79769313486231063271e+308,X'66E62440AE47E17A14AEF33F33B323C0007862A441A7C043');
>  
>
> COMMIT;
>
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread Jean Chevalier
Please provide your code context, as in,

http://stackoverflow.com/questions/10746237/sqlite-in-c-sharp-throws-invalidcastexception-using-getbytes

Today, Bill wrote:
>
> All,
> Below is a .dump of the database I'm working with. I can use
> GetBytes() successfully on all the BLOB columns except
> myTextArray. On that column I get a
> System.InvalidCastException error. Can anyone tell me why?
> Thanks
> -Bill
>


[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread Simon Slavin

On 2 Jul 2015, at 12:47pm, William Drago  wrote:

> Below is a .dump of the database I'm working with. I can use GetBytes() 
> successfully on all the BLOB columns except myTextArray. On that column I get 
> a System.InvalidCastException error. Can anyone tell me why? Thanks.

SQLite has no inherent understanding of arrays.  Although your code looks like 
it should just be storing and recalling the string

"blue" "red" "orange" "yellow"

with its quotes and space I suspect that some part of the Reader.GetBytes() 
routine is assuming it will get an array, whereas it's really just getting a 
chunk of octets.

You may have to read the column into text, then use your language to split the 
text up into array elements.

Simon.


[sqlite] Reader.GetBytes() - when is a byte not a byte?

2015-07-02 Thread William Drago
All,

Below is a .dump of the database I'm working with. I can use 
GetBytes() successfully on all the BLOB columns except 
myTextArray. On that column I get a 
System.InvalidCastException error. Can anyone tell me why? 
Thanks.

-Bill


---.dump file---

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE myTable (

myText Text,

myTextArray BLOB, --Text

myBool Boolean,

myBoolArray BLOB, --Boolean

myUInt8 UInt8,

myUInt8Array BLOB, --UInt8

myUInt16 UInt16,

myUInt16Array BLOB, --UInt16

myInt16 Int16,

myInt16Array BLOB, --Int16

myInt32 Int32,

myInt32Array BLOB, --Int32

myInt64 Int64,

myInt64Array BLOB, --Int64

myReal32 Real32,

myReal32Array BLOB, --Real32

myReal64 Real64,

myReal64Array BLOB --Real64

);
INSERT INTO "myTable" VALUES('This is text','"blue" "red" 
"orange" 
"yellow"',0,X'00010001',255,X'FFFEFDFCFBFAF9F8F7F6',65535,X'FEFFFDFFFCFFFBFFFAFFFAFFFBFFFCFFFDFF',32767,X'FF7F01800100020003000400050006000700',2147483647,X'FF7F00800100',9223372036854775807,X'FF7F00800100',3.40282346638528897567e+38,X'7F7F70443901803F004040408040A040C040E040',1.79769313486231063271e+308,X'66E62440AE47E17A14AEF33F33B323C0007862A441A7C043');
COMMIT;