AnantLabs / codesmith

Automatically exported from code.google.com/p/codesmith
1 stars 0 forks source link

Varbinary retrieval bug - ADOHelper - VB.NET / CSLA #513

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
- Storing a field in the database of type Varbinary(MAX) and retrieving it.

I was trying to retrieve a photo from a SQL database and noticed that it's 
going through this routine.  I also noticed that length was being stored in the 
db correctly, but that when it returned it was larger than the original by the 
actual number of 1024 blocks in it.  This routine is used on lastChanged, but 
it's only 8 bytes, so it probably never showed up.  I added the "-1" to the 
bytesRead argument and the problem went away.

I am *not* much of a coder, so I haven't thought through the implications of 
making this change.  I just know that my photos are now going in and out just 
fine.

This code is not overwritten on regeneration, but developers will need to fix 
it when they generate the first time in a project.

Here's the code:
        Public Shared Function GetBytes(ByVal reader As SafeDataReader, 
                ...
                ...
                    Dim actualRead As Byte() = New Byte(bytesRead) {}
                ...
                ...
                ...
        End Function  

Here's what it should be:
        Public Shared Function GetBytes(ByVal reader As SafeDataReader, 
                ...
                ...
                    Dim actualRead As Byte() = New Byte(bytesRead - 1) {}
                ...
                ...
                ...
        End Function  

Original issue reported on code.google.com by bill.n...@gmail.com on 5 Oct 2010 at 2:29

GoogleCodeExporter commented 9 years ago
Correction:  The header in the code says changes will not be lost on 
regeneration, but in fact, they are.  FYI

Original comment by bill.n...@gmail.com on 5 Oct 2010 at 2:39

GoogleCodeExporter commented 9 years ago
Hello,

Thanks I have updated the comments. Could you show me the table definition you 
are using as well as a snippet of code you are using to get/insert this data. 
This will help me to reproduce this issue.

Thanks
-Blake Niemyjski

Original comment by bniemyjski on 5 Oct 2010 at 10:38

GoogleCodeExporter commented 9 years ago
This issue was updated by revision r1988.

Updated the Comments in ADOHelper.cst to reflect that changes could be lost.

Original comment by bniemyjski on 5 Oct 2010 at 10:39

GoogleCodeExporter commented 9 years ago
Blake:

As you can see in the code below, I am getting an image from a disk file (had 
to start somewhere) and putting it into a fresh Account object.  I update a few 
more fields so that it'll pass validation and then save it.  I turn right 
around and read it back and then compare, byte by byte, the results.  You have 
to do this with an image that's greater than 1024 bytes.

Bill

Here's the code I dummied up to put a photo in the record:
        Private Sub OnCreated()
            'Read the file and convert it to Byte Array 
            Dim filePath As String = "C:\Users\bill\Pictures\blackfridaycrowd.jpg"
            Dim filename As String = Path.GetFileName(filePath)
            Dim fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)

            Dim br As BinaryReader = New BinaryReader(fs)
            Dim bytes As Byte() = br.ReadBytes(Convert.ToInt32(fs.Length))
            br.Close()
            fs.Close()
            Photo = bytes
        End Sub

And here's my test code:
Module Module1

    Sub Main()
        Dim a1 As Account = Account.NewAccount
        a1.LastName = "test last"
        a1.FirstName = "first test"
        a1.Email = "email"
        a1 = a1.Save

        Console.WriteLine("ID: {0} - Photo size {1}", a1.Identification.ToString, a1.Photo.Length.ToString)
        Dim a As Account = Account.GetByIdentification(a1.Identification)
        Console.WriteLine("ID: {0} - Photo size {1}", a.Identification.ToString, a.Photo.Length.ToString)

        Dim j As Integer = 0
        For j = 0 To 1500
            If a1.Photo.ElementAt(j) <> a.Photo.ElementAt(j) Then
                Console.WriteLine(String.Format("Mismatch at: {0}", j.ToString))
                Console.WriteLine(String.Format("a1: {0}, a:{1}", a1.Photo.ElementAt(j - 1).ToString, a.Photo.ElementAt(j - 1).ToString))
                Console.WriteLine(String.Format("a1: {0}, a:{1}", a1.Photo.ElementAt(j).ToString, a.Photo.ElementAt(j).ToString))
                Console.WriteLine(String.Format("a1: {0}, a:{1}", a1.Photo.ElementAt(j + 1).ToString, a.Photo.ElementAt(j + 1).ToString))
                Console.ReadLine()
            End If
        Next

        Console.ReadLine()
    End Sub

And here's the table definition:
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Accounts](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [firstName] [nvarchar](50) NOT NULL,
    [lastName] [nvarchar](50) NOT NULL,
    [gamerTag] [nvarchar](50) NULL,
    [email] [nvarchar](50) NOT NULL,
    [accountType] [int] NOT NULL,
    [accountStatus] [int] NOT NULL,
    [dateRegistered] [datetime] NOT NULL,
    [referringAccount] [int] NULL,
    [sex] [int] NOT NULL,
    [cellPhone] [nchar](10) NULL,
    [notes] [nvarchar](max) NULL,
    [dateOfBirth] [date] NULL,
    [archived] [bit] NOT NULL,
    [photo] [varbinary](max) NULL,
    [lastChanged] [timestamp] NOT NULL,
 CONSTRAINT [PK_NHAccounts] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

Original comment by bill.n...@gmail.com on 8 Oct 2010 at 2:15

GoogleCodeExporter commented 9 years ago
Hello,

I didn't see the reply to this. I'll set this up scenario and get back to you.

Thanks
-Blake

Original comment by bniemyjski on 18 Nov 2010 at 1:46

GoogleCodeExporter commented 9 years ago
Thanks

Original comment by bill.n...@gmail.com on 18 Nov 2010 at 2:09

GoogleCodeExporter commented 9 years ago
This issue was updated by revision r2051.

Fixed Varbinary retrieval bug - ADOHelper - VB.NET / CSLA

Original comment by bniemyjski on 20 Nov 2010 at 12:16

GoogleCodeExporter commented 9 years ago
Hello,

This bug has been fixed in revision 2051 and can be downloaded from here 
(http://community.codesmithtools.com/nightly/CSLA/)

Thanks
-Blake Niemyjski

Original comment by bniemyjski on 20 Nov 2010 at 12:19