Latest Entries »

Monday, August 23, 2010

# .netTiers. make data:repeater behave like asp:Repeater with OnCommand event

Hello. Today I would like to share with you with my expirience around strongly typed controls in nettiers.
  and 

Normally if developer want put control causing PostBack in Repeater should give CommandName , CommandArgument in PostBack Control and provide Repeater_OnCommand (or OnClick,OnCommand in child control) method. Badly data:Repeaters doesn't have onCommand Event and even postback in child control OnClick and OnCommand is not firing. Code below is nice but doesn't work:

<data:GblLanguageRepeater ID="nTiersGblRepeater" runat="server" DataSourceID="GblLanguageDataSource1">
    <ItemTemplate>
        <asp:LinkButton runat="server" ID="LangFlagLb2" CommandName="GblLanguageId" CommandArgument='<%# Container.GblLanguageId %>'
            OnCommand="LangFlagLb_Command" OnClick="LangFlagLb_Click" >
            <asp:Image runat="server" ID="LangFlagImg2" ImageUrl='<%# Container.LanguageFlag %>'
                ToolTip='<%# Container.LanguageDescription %>' />
        </asp:LinkButton>
    </ItemTemplate>
</data:GblLanguageRepeater>
<data:GblLanguageDataSource ID="GblLanguageDataSource1" runat="server" SelectMethod="GetAll">
</data:GblLanguageDataSource>
Any method listed below won't fire.

//LinkButton OnCommand Event
    protected void LangFlagLb_Command(object sender, CommandEventArgs e)
    {
        if (e.CommandName.ToString() == "GblLanguageId")
        {
            int GblLanguageId = int.Parse(e.CommandArgument.ToString());
            this.Profile.GblGroup.GblLanguageId = GblLanguageId;
            CurrentLangLit.Text = mgr.Data.DataRepository.GblLanguageProvider.GetByGblLanguageId(this.Profile.GblGroup.GblLanguageId).LanguageDescription;
        }
    }
//Repeater OnCommand Event
    protected void GblLangRep_ItemCommand(object sender, RepeaterCommandEventArgs e)
    {
        if (e.CommandName.ToString() == "GblLanguageId")
        {
            int GblLanguageId = int.Parse(e.CommandArgument.ToString());
            this.Profile.GblGroup.GblLanguageId = GblLanguageId;
            CurrentLangLit.Text = mgr.Data.DataRepository.GblLanguageProvider.GetByGblLanguageId(this.Profile.GblGroup.GblLanguageId).LanguageDescription;
        }
    }
//LinkButton Click Event
    protected void LangGlagLb_Click(object sender, EventArgs e)
    {
        LinkButton r = sender as LinkButton;
        if (r.CommandName.ToString() == "GblLanguageId")
        {
            int GblLanguageId = int.Parse(r.CommandArgument.ToString());
            this.Profile.GblGroup.GblLanguageId = GblLanguageId;
            CurrentLangLit.Text = mgr.Data.DataRepository.GblLanguageProvider.GetByGblLanguageId(this.Profile.GblGroup.GblLanguageId).LanguageDescription;
        }
    }

Code that works.

First thing about is change data:GblRepeater into normal asp:Repeater control and secondly we will put at the top of control directive to import Container Item namespace.

<%@ Import Namespace="mgr.Entities" %>

And change CommandArgumend,CommandName,Tooltip:

<asp:Repeater ID="GblLangRep" runat="server" DataSourceID="GblLangDs" OnCommand="GblLangRep_ItemCommand">
    <ItemTemplate>
        <asp:LinkButton runat="server" ID="LangFlagLb" CommandName="GblLanguageId" CommandArgument='<%# (Container.DataItem as GblLanguage).GblLanguageId %>'
            OnCommand="LangFlagLb_Command">
            <asp:Image runat="server" ID="LangFlagImg" ImageUrl='<%# (Container.DataItem as GblLanguage).LanguageFlag %>'
                ToolTip='<%# (Container.DataItem as GblLanguage).LanguageDescription %>' />
        </asp:LinkButton>
    </ItemTemplate>
</asp:Repeater>
<data:GblLanguageDataSource runat="server" ID="GblLangDs" SelectMethod="GetAll" />


Now you can do whatever you want in OnCommand event in Repeater or OnClick(OnCommand) Event in LinkButton. After some reaserch in google I found that next version of nettiers should fix the problem with PostBack Events.

Monday, July 12, 2010

SELECT MAX String FROM TABLE

Dzień dobry. Niedawno spotkałem się z potrzebą wyświetlenia najdłuższego napisu z tabeli bazy danych. Ku mojemu zdziwieniu zapytanie MAX(kolumna nvarchar) nie zwróciła najdłuższego napisu a jakiś bezsensowny. Podejrzewam, że silnik MSSQL zsumował wartość każdej litery w napisie zmieniając ją w wartość liczbową dlatego też była potrzeba utworzenia własnego sposobu na wykonanie czynności.

Funkcja jest bardzo prosta: obcina z obu stron: ltrim rtrim kolumnę z napisem, a następnie otrzymujemy długość napisu funkcją LEN. Gdy już posiadamy długość napisu to wykonujemy zapytanie WHERE LEN(Kolumna) = największa długość napisu.

Zatem to dzieła:


CREATE FUNCTION [dbo].[GetMaxLenghtString]()
RETURNS TABLE 
AS
RETURN 
(
SELECT LEN(Title) as Lenght,Title FROM Books WHERE LEN(Title) = (SELECT max(len(ltrim(rtrim(Title)))) from Books)
)
GO

Żeby zobaczyć wynik musimy wykonać odpowiednie zapytanie:

select * from GetMaxLenghtString()

Funkcja ta zwróci najdłuższy napis. Gdy będzie kilka takich napisów wynikowa tabela będzie zawierać kilka wierszy. Można doprawić do smaczku funkcję aby zwracała 1 wartość umieszczająć po SELECT klauzulę DISTINCT.

Dziękuję.

Monday, July 5, 2010

#MSSQL - SELECT BOTTOM FROM table

Dzień dobry. Dzisiaj chciałbym przedstawić pewną procedurę, której głównym zadaniem będzie pobranie dowolnej ilości wierszy ostatnio dodanych do tabeli. Jak wiadomo do pobrania n-pierwszych rekordów służy polecenie:


SELECT TOP(@PARAM) FROM TABLE ORDER BY COLUMN

Wykorzystamy klauzylę TOP wraz z ORDER BY PRIMARY_KEY DESC(majejąco), aby wybrać N-wierszy spośród tabeli. Zatem utwórzmy przykładową tabelę:

CREATE TABLE [dbo].[Sonda](
 [SondaId] [int] IDENTITY(1,1) NOT NULL,
 [Typ] [bit] NOT NULL,
 [Tytul] [nvarchar](256) NOT NULL,
 [Widocznosc] [bit] NOT NULL,
 [Dodano] [datetime] NOT NULL,
 [KtoDodal] [nvarchar](256) NOT NULL,
 [MaxOdpowiedzi] [int] NOT NULL,
 CONSTRAINT [PK_Sonda] PRIMARY KEY CLUSTERED 
(
 [SondaId] 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
Teraz wstawimy 10 rekordów
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 1',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 2',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 3',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 4',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 5',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 6',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 7',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 8',0,GETDATE(),'admin',25)
INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
     VALUES (0,'Testowa sonda 9',0,GETDATE(),'admin',25)
 INSERT INTO Sonda(Typ,Tytul,Widocznosc,Dodano,KtoDodal,MaxOdpowiedzi)
 VALUES (0,'Testowa sonda 10',0,GETDATE(),'admin',25)
GO

Skoro mamy już tabelę i rekordy to nadszedł czas na procedurę, która pobierze ostatnio dodane wiersze:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Sonda_GetSondaBottom]
 @Limit int
AS
BEGIN
 SET NOCOUNT ON;
 SELECT  top (@Limit) * FROM Sonda ORDER BY SondaId DESC
END

Na koniec przetestujemy naszą procedurę:
EXEC [dbo].[Sonda_GetSondaBottom]
  @Limit = 10


Post zainspirowany tekstem: http://particletree.com/notebook/select-last-100-records/

Sunday, July 4, 2010

#ASM. Wyświetlanie danych z bufora klawiatury. Mój pierwszy sukces.

Dzień dobry. Dzisiaj chciałbym zaprezentować przykład prostego programu w assemblerze. Program ten wyświetla napis proszący o podanie imienia, a następnie go wyświetla w nowej linii. Do poprawnego skompilowania i uruchomienia potrzeba tasm.exe, tlink.exe, oraz DPMIMEM.DLL
Kompilacja : tasm prog1.asm
Linkowanie: tlink prog1.obj
Wynik: prog1.exe



;Moj 1 program wczytuje dane z bufora i je wyswietla
MODEL TINY
STACK 24H
DATASEG
 napis db "Podaj swoje imie: $"
 imie db 20,0,10,13,20 dup("$")
 enters db 10,13,"$"
CODESEG
START:
 xor ax,ax ;zerowanie ax dla pewnosci
 mov ax,@DATA
 mov ds,ax
 ;wyswietlenie napis
 lea dx,napis;mov dx,offset napis
 mov ah,9
 int 21h
 ;wczytaj do imie
 mov ah,0ah
 mov dx, offset imie
 int 21h
 ;wyswietl znak powrotu karetki i nowej linii
 mov ah,9
 mov dx,offset enters
 int 21h
 ;wyswietl dane z imie
 mov ah,9
 mov dx, offset[imie+2]
 int 21h
 ;czekanie na znak
 mov ah,8
 int 21h
 mov ah,4ch;mov ax,4c00h
 int 21h
END START


Zacznijmy od początku, czyli deklaracji zmiennych:

napis db "Podaj swoje imie: $"
 imie db 20,0,20 dup("$")
 enters db 10,13,"$"

Pierwsza zmienna wyświetla się na początku programu i jest deklarowana jako declare byte.
Druga zmienna to ciąg bajtów w których: 20 oznacza maksymalną długość bufora, 0 będzie oznaczać realną wczytaną długość bufora z klawiatury.Z kolei 20 dup("$") dla TASM-a oznacza zadeklarowanie 20 bajtów o zawartości $. Dlaczego? Ponieważ każdy ciąg znaków w asm musi się kończyć znakiem dolara.

xor ax,ax ;zerowanie ax dla pewnosci
 mov ax,@DATA
 mov ds,ax

W tym miejscu przenosimy segment danych do rejestrów ds i ax.

;wyswietlenie napis
 lea dx,napis;mov dx,offset napis
 mov ah,9
 int 21h

Tutaj wrzucamy do dx offset(przesunięcie względem segmentu) zmiennej napis, następnie do ah wrzucamy wartość 9 i wywołujemy przerwanie dos-a 21H.

;wczytaj do imie
 mov ah,0ah
 mov dx, offset imie
 int 21h

Tak samo jak powyżej ale korzystamy z funkcji 0Ah przerwania 21H dos-u. W rejestrze DX będzie spoczywał wpisany ciąg do bufora.

;wyswietl znak powrotu karetki i nowej linii
 mov ah,9
 mov dx,offset enters
 int 21h
 ;wyswietl dane z imie
 mov ah,9
 mov dx, offset[imie+2]
 int 21h
 ;czekanie na znak
 mov ah,8
 int 21h
 mov ah,4ch;mov ax,4c00h
 int 21h

W powyższym fragmencie powtarzamy wyświetlenie danych(ah 9,int 21H) z tym, że w wyświetlaniu danych z imienia zaczynamy od 2 bajtu(0 bajt zarezerwowaliśmy na długość ciągu, 1 bajt dla faktycznej długości ciągu. Liczymy od zera of course.). Na koniec czekamy na dowolny klawisz klawiatury.

Na koniec podrzucam bardzo pomocną literaturę:
Polski kurs asm:http://rudy.mif.pg.gda.pl/~bogdro/
Zbiór wszystkich przerwań dosu:http://www.ctyme.com/intr/int.htm

Pozdrowienia!

Tuesday, June 22, 2010

#Java - Dodawanie i pobieranie zdjęcia z bazy mysql

Czasami może się zdarzyć, że potrzebujemy przechować obrazek/zdjęcie w jakiejś tabeli bazy danych mysl. Najpierw wypadało by stworzyć tabelę, która będzie przechowywać nasze dane. Obrazki i inne pliki binarne przechowywujemy w typie danych BLOB. Tak wygląda przykładowa tabela:

CREATE TABLE IF NOT EXISTS `zdjecie` (
  `ID_Zdjecia` int(11) NOT NULL AUTO_INCREMENT,
  `Opis` varchar(150) COLLATE utf8_polish_ci NOT NULL DEFAULT '-',
  `Zdjecie` blob NOT NULL,
  PRIMARY KEY (`ID_Zdjecia`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci

A teraz do operowania na bazie danych będziemy posługiwać się 2 metodami:

//Wstawienie zdjęcia
    public void InsertZdjecie(int ID_Osoba,String Opis,FileInputStream fotos);
    //pobranie z bazy zdjęcia
    public  BufferedImage getMySqlPhoto(int ID_Zdjecie);

I ich definicja:
public  BufferedImage getMySqlPhoto(int ID_Zdjecie){
        BufferedImage BI = null;
        Statement S;
        ResultSet rs;
        String sqlStatement = "SELECT zdjecie FROM zdjecie WHERE ID_Zdjecia = '"+ID_Zdjecie+"'";
        try {
            S = con.createStatement();
            rs = S.executeQuery(sqlStatement);
            if (rs.next()){
                Blob image = rs.getBlob("Zdjecie");
                InputStream input = image.getBinaryStream();
                BI=ImageIO.read(input);
                // set read buffer size
                input.close();
            }
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
        return BI;
    }
    public void InsertIntoZdjecie(String Opis,FileInputStream fotos)
    {
        String INSERT = "INSERT INTO ZDJECIE(Opis,Zdjecie) VALUES (?,?)";
        System.out.println(INSERT);
        PreparedStatement ps1;

        try {
            ps1 = con.prepareStatement(INSERT);
            ps1.setString(1, Opis);
            ps1.setBinaryStream(2, fotos);
            ps1.executeUpdate();
        } catch (SQLException ex) {
            ex.printStackTrace();
            
        }
    }

Prawda, że proste ? :-)

Sunday, February 7, 2010

Icefaces 2.0 Alfa 2 NetBeans 6.8 modules.

O właśnie na to czekałem od jakiś dwóch miesięcy !! Jako, że zauważyłem wiele ułatwień dla programisty w frameworku JavaServer Faces 2.0 i NB 6.8, a wcześniej korzystałem z biblioteki znaczników icefaces 1.8.2, która nie była wspierana w najnowszych JSF-ach to niestety odłożyłem na jakiś czas programowanie java EE. Teraz na pewno gdy znajdę chwilkę czasu (albowiem intensywnie przeportowywuję się z java na .NET) to zacznę coś projektować.

Link: