рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рдпреВрдбреАрдЖрд░ рд▓рд┐рдЦрдирд╛

рдлрд╛рдпрд░рдмрд░реНрдб рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ - рдпреВрдбреАрдПрдл (рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд╛рд░реНрдп) рд▓рд┐рдЦрдХрд░ PSQL рднрд╛рд╖рд╛ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред рдпреВрдбреАрдПрдл рдХреЛ рд▓рдЧрднрдЧ рдХрд┐рд╕реА рднреА рд╕рдВрдХрд▓рд┐рдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдлрд╛рдпрд░рдмрд░реНрдб 3.0 рдиреЗ рдлрд╛рдпрд░рдмрд░реНрдб рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧ-рдЗрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкреЗрд╢ рдХрд┐рдпрд╛ред рдЗрди рдкреНрд▓рдЧрдЗрдиреНрд╕ рдореЗрдВ рд╕реЗ рдПрдХ рдмрд╛рд╣рд░реА рдЗрдВрдЬрди (рдмрд╛рд╣рд░реА рдЗрдВрдЬрди) рд╣реИред рдпреВрдбреАрдЖрд░ (рдпреВрдЬрд░ рдбрд┐рдлрд╛рдЗрдВрдб рд░реВрдЯреАрди - рдпреВрдЬрд░ рдбрд┐рдлрд╛рдЗрдВрдб рд░реВрдЯреАрди) рдореИрдХреЗрдирд┐рдЬреНрдо рдлрд╛рдпрд░рдмреНрд░рд┐рдбрдПрдХреНрд╕рдЯрд░реНрдирд▓ рдЗрдВрдЬрди рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдКрдкрд░ рдПрдХ рд▓реЗрдпрд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИред


рдЗрд╕ рдЧрд╛рдЗрдб рдореЗрдВ, рд╣рдо рдЖрдкрдХреЛ рдмрддрд╛рдПрдВрдЧреЗ рдХрд┐ рдпреВрдбреАрдЖрд░ рдХреА рдШреЛрд╖рдгрд╛ рдХреИрд╕реЗ рдХрд░реЗрдВ, рдЙрдирдХреЗ рдЖрдВрддрд░рд┐рдХ рддрдВрддреНрд░, рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рдпреВрдбреАрдЖрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдирдИ рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдХреБрдЫ рдкрд╣рд▓реБрдУрдВ рдХреЛ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рдЯрд┐рдкреНрдкрдгреА

рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╛рдпрд░рдмрд░реНрдб рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпреВрдбреАрдЖрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рд╕рд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред
рд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдпреВрдбреАрдЖрд░ рдХреЗ рд▓рд┐рдЧреЗрд╕реА рдпреВрдбреАрдПрдл рдкрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╛рдпрджреЗ рд╣реИрдВ:


  • рдЖрдк рди рдХреЗрд╡рд▓ рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рд╕реНрдХреЗрд▓рд░ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рд╕рдВрдЧреНрд░рд╣реАрдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ (рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдФрд░ рдЪрдпрдирд╛рддреНрдордХ рджреЛрдиреЛрдВ), рд╕рд╛рде рд╣реА рдЯреНрд░рд┐рдЧрд░ рднреА рдХрд░рддреЗ рд╣реИрдВ;
  • рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдмреЗрд╣рддрд░ рдирд┐рдпрдВрддреНрд░рдгред рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ (рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдкрд╛рд╕) рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЕрдиреНрдп рдЧреБрдгреЛрдВ рдХреЛ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдк рдЗрди рдЧреБрдгреЛрдВ рдХреЛ рдпреВрдбреАрдПрдл рдХреЗ рдЕрдВрджрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпреВрдбреАрдЖрд░ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдзрд┐рдХ рдПрдХреАрдХреГрдд рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдирд┐рдпрдорд┐рдд PSQL рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣реИ;
  • рдпреВрдбреАрдЖрд░ рд╡рд░реНрддрдорд╛рди рдХрдиреЗрдХреНрд╢рди рдпрд╛ рд▓реЗрдирджреЗрди рдХрд╛ рд╕рдВрджрд░реНрдн рдЙрдкрд▓рдмреНрдз рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
    рдЗрд╕ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдЬреЛрдбрд╝рддреЛрдбрд╝;
  • рдЕрдкрд╡рд╛рдж рд╣реЛрдиреЗ рдкрд░ рдлрд╝рд╛рдпрд░рдмрд░реНрдб рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ; рд╡рд┐рд╢реЗрд╖ рдорд╛рди рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ;
  • рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ (UDR) рдХреЛ PSQL рдкреИрдХреЗрдЬ рдореЗрдВ рд╡рд░реНрдЧреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ;
  • рдпреВрдбреАрдЖрд░ рдХреЛ рдХрд┐рд╕реА рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд), рдЗрд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд╕рдВрдмрдВрдзрд┐рдд рдмрд╛рд╣рд░реА рдЗрдВрдЬрди рдкреНрд▓рдЧ-рдЗрди рд▓рд┐рдЦрд╛ рдЬрд╛рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрд╛рд╡рд╛ рдпрд╛ рдХрд┐рд╕реА рднреА .NET рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧрдЗрдиреНрд╕ рд╣реИрдВред

рдЯрд┐рдкреНрдкрдгреА

рд╡рд░реНрддрдорд╛рди UDR рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди PSQL рд╕реНрдЯрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рдЕрдиреБрдкрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдпреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ред рдЯреЛрдкреА
рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдирдореНрдпрддрд╛ рдХреЗ рдХрд╛рд░рдг рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдкрд░рд┐рдгрд╛рдо
UDR рдФрд░ UDF рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ UDR рд▓рдЧрднрдЧ рд╣реИ
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рджреЛ рддрд░реНрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ 2.5 рдЧреБрдирд╛ рдзреАрдорд╛ред рдЧрддрд┐
UDR рд▓рдЧрднрдЧ рдПрдХ рдирд┐рдпрдорд┐рдд PSQL рдлрд╝рдВрдХреНрд╢рди рдХреА рдЧрддрд┐ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рд╢рд╛рдпрдж рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдпрд╣
рдкрд▓ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ, рдпрд╣ рдУрд╡рд░рд╣реЗрдб рдмрди рд╕рдХрддрд╛ рд╣реИ
рдЕрддреАрдиреНрджреНрд░рд┐рдпред

рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рднрд╛рдЧреЛрдВ рдореЗрдВ, рдЬрдм рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП,
рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рдЯреНрд░рд┐рдЧрд░ рдХрд╛ рдорддрд▓рдм рд╣рдо рдмрд┐рд▓реНрдХреБрд▓ рдпреВрдбреАрдЖрд░ (рдФрд░ рдпреВрдбреАрдПрдл рдирд╣реАрдВ) рд╣реЛрдЧрд╛ред


рдЯрд┐рдкреНрдкрдгреА

рд╣рдорд╛рд░реЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг рдбреЗрд▓реНрдлреА 2009 рдФрд░ рдмрд╛рдж рдореЗрдВ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдлреНрд░реА рдкрд╛рд╕реНрдХрд▓ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╕рдм
рдЙрджрд╛рд╣рд░рдг рдбреЗрд▓реНрдлреА рдФрд░ рдлреНрд░реА рдкрд╛рд╕реНрдХрд▓ рджреЛрдиреЛрдВ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрджрд┐
рдЕрд▓рдЧ рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВред

рдлрд╛рдпрд░рдмрд░реНрдб рдПрдкреАрдЖрдИ


рд╕рдВрдХрд▓рд┐рдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ, рдХрд╛рд░реНрдпреЛрдВ рдпрд╛ рдЯреНрд░рд┐рдЧрд░реНрд╕ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдирдП рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдлрд╛рдпрд░рдмрд░реНрдб рдПрдкреАрдЖрдИ рдХреЗ рдЬреНрдЮрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рдЧрд╛рдЗрдб рдореЗрдВ рдлрд╛рдпрд░рдмрд░реНрдб рдПрдкреАрдЖрдИ рдХрд╛ рдкреВрд░рд╛ рд╡рд┐рд╡рд░рдг рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЖрдк рдЗрд╕реЗ Firebird ( doc/Using_OO_API.html ) рдХреЗ рд╕рд╛рде рд╡рд┐рддрд░рд┐рдд рдкреНрд░рд▓реЗрдЦрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


рд╡рд┐рднрд┐рдиреНрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧ-рдЗрди, рдЬрд┐рдирдореЗрдВ рдПрдкреАрдЖрдИ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП рдлрд╛рдпрд░рдмрд░реНрдб рд╡рд┐рддрд░рдг рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рддрд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЖрдк рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдирдХреНрд╕-рд╡рд┐рддрд░рд┐рдд рд╕рдВрдХреБрдЪрд┐рдд рддрд╛рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ (/ /opt/firebird/include/firebird/Firebird.pas рд╕рдВрдЧреНрд░рд╣ рдХреЗ рдЕрдВрджрд░ рдкрде) рд╕реЗ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред


CLOOP


CLOOP - рдХреНрд░реЙрд╕ рд▓реИрдВрдЧреНрд╡реЗрдЬ рдСрдмреНрдЬреЗрдХреНрдЯ рдУрд░рд┐рдПрдВрдЯреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧред рдпрд╣ рдЙрдкрдХрд░рдг рдлрд╛рдпрд░рдмрд░реНрдб рдХреЗ рд╕рд╛рде рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЗрд╕реЗ рд╕реЛрд░реНрд╕ рдХреЛрдб https://github.com/FirebirdSQL/firebird/tree/B3_0_Release/extern/cloop рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЯреВрд▓ рдЕрд╕реЗрдВрдмрд▓ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк include/firebird/FirebirdInterface.idl рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рд╡рд░рдг рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрдкрдиреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ ( IdlFbInterfaces.h рдпрд╛ Firebird.pas ) рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдкреАрдЖрдИ рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рд╕реНрдХрд▓ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:


 cloop FirebirdInterface.idl pascal Firebird.pas Firebird --uses SysUtils \ --interfaceFile Pascal.interface.pas \ --implementationFile Pascal.implementation.pas \ --exceptionClass FbException --prefix I \ --functionsFile fb_get_master_interface.pas 

Pascal.interface.pas , Pascal.implementation.pas рдФрд░ fb_get_master_interface.pas https://github.com/FirebirdSQL/firebird/tree-B3_0_Release/src/misc/pascal рдкрд░ fb_get_master_interface.pas рдЬрд╛ рд╕рдХрддреА рд╣реИрдВред


рдЯрд┐рдкреНрдкрдгреА

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдлрд╛рдпрд░рдмрд░реНрдб рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдЙрдкрд╕рд░реНрдЧ I рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╕реНрдерд┐рд░рд╛рдВрдХ


рдкрд░рд┐рдгрд╛рдореА Firebird.pas рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдИ isc_* рд╕реНрдерд┐рд░рд╛рдВрдХ рдирд╣реАрдВ рд╣реИрдВред C / C ++ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдпреЗ рд╕реНрдерд┐рд░рд╛рдВрдХ https://github.com/FirebirdSQL/firebird/blob/B3_0_Release/src/include/consts_pub.h рдкрд░ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╛рд╕реНрдХрд▓ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░рд╛рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП AWK рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рд╡рд┐рдВрдбреЛрдЬ рдкрд░, рдЖрдкрдХреЛ рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП рдЧреЙрд╡ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдпрд╛ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП рд╡рд┐рдВрдбреЛрдЬ рд╕рдмрд╕рд┐рд╕реНрдЯрдо (рд╡рд┐рдВрдбреЛрдЬ 10 рдкрд░ рдЙрдкрд▓рдмреНрдз) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:


 awk -f Pascal.Constants.awk consts_pub.h > const.pas 

рдкрд░рд┐рдгрд╛рдореА рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ Firebird.pas рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЦрд╛рд▓реА рдХрдмреНрдЬ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд▓рд╛рдЧреВ рд╣реЛрдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред Pascal.Constants.awk рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
https://github.com/FirebirdSQL/firebird/tree/B3_0_Release/src/misc/pascal ред


рд▓рд╛рдЗрдл рдЯрд╛рдЗрдо рдореИрдиреЗрдЬрдореЗрдВрдЯ


рдлрд╛рдпрд░рдмрд░реНрдб рдЗрдВрдЯрд░рдлреЗрд╕ COM рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдирдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдЕрд▓рдЧ рд╣реИред


рдлрд╛рдпрд░рдмрд░реНрдб рдореЗрдВ рджреЛ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣реИрдВ рдЬреЛ рд▓рд╛рдЗрдл рдЯрд╛рдЗрдо рдореИрдиреЗрдЬрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ: рдЖрдЗрдбреАрдПрд╕реЛрдкреЙрд▓рд┐рдлрд╝рд┐рдХ рдФрд░ рдЖрдИрдЖрд░рдЗрдиреНрдлреИрдХреНрд╢рдиред рдЕрдиреНрдп рдЗрдВрдЯрд░рдлреЗрд╕ рдмрдирд╛рддреЗ рд╕рдордп рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдХреНрд░рд┐рдп рд╣реЛрддрд╛ рд╣реИ: рдкреНрд▓рдЧ-рдЗрди рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдХрдИ рдЕрдиреНрдп рдЗрдВрдЯрд░рдлреЗрд╕ рдХреА рддрд░рд╣, IPlugin рд▓рд┐рдВрдХ рдХреЛ рдЧрд┐рдирддрд╛ рд╣реИред рдЗрдирдореЗрдВ рд╡реЗ рдЗрдВрдЯрд░рдлреЗрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕, рд▓реЗрдирджреЗрди рдкреНрд░рдмрдВрдзрди рдФрд░ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╕реЗ рдЬреБрдбрд╝рдиреЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред


рд╕рдВрджрд░реНрдн рдЧрд┐рдирддреА рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдУрд╡рд░рд╣реЗрдб рд╣рдореЗрд╢рд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореБрдЦреНрдп рдЗрдВрдЯрд░рдлрд╝реЗрд╕, рдЬреЛ рд╢реЗрд╖ API рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, IMaster, рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрд╕реАрдорд┐рдд рдЬреАрд╡рдирдХрд╛рд▓ рд╣реИред рдЕрдиреНрдп рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП, рдЬреАрд╡рдирдХрд╛рд▓ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рд╕реЗ рдХрдбрд╝рд╛рдИ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИ; IStatus рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдирд╣реАрдВ рд╣реИ
рдереНрд░реЗрдбред рд╕реАрдорд┐рдд рдЬреАрд╡рдирдХрд╛рд▓ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреН, рдирд┐рдкрдЯрд╛рди () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИред


рдорджрдж

рдпрджрд┐ рдЖрдк рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрдИ рд╡рд╕реНрддреБ рдХреИрд╕реЗ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддреЛ рдЗрд╕рдХреА рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЛ рджреЗрдЦреЗрдВ, рдпрджрд┐ рдпрд╣ рд╣реИ
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ IReferenceCounted, рдлрд┐рд░ рд╕рдВрджрд░реНрдн рдЧрд┐рдирддреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░ рд╕рдВрджрд░реНрдн рдЧрд┐рдирддреА рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ
рд░рд┐рд▓реАрдЬ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд╕рдВрджрд░реНрдн рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдХрдо рдХрд░реЗрдВред

рдпреВрдбреАрдЖрд░ рдХреА рдШреЛрд╖рдгрд╛


рдпреВрдбреАрдЖрд░ рдХреЛ рдбреАрдбреАрдПрд▓ рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЬреЛрдбрд╝рд╛ рдпрд╛ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдЖрдк рдирд┐рдпрдорд┐рдд рдкреАрдПрд╕рдХреНрдпреВрдПрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ, рдХрд╛рд░реНрдпреЛрдВ рдпрд╛ рдЯреНрд░рд┐рдЧрд░реНрд╕ рдХреЛ рдЬреЛрдбрд╝рддреЗ рдпрд╛ рд╣рдЯрд╛рддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЯреНрд░рд┐рдЧрд░ рдмреЙрдбреА рдХреЗ рдмрдЬрд╛рдп, рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЗрд╕рдХрд╛ рд╕реНрдерд╛рди рдмрд╛рд╣рд░реА рдирд╛рдо рдЦрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдЗрд╕ рд╡рд╛рдХреНрдп рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдпрд╣ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ, рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдЯреНрд░рд┐рдЧрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╣реЛрдЧрд╛ред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 EXTERNAL NAME '<extname>' ENGINE <engine> [AS <extbody>] <extname> ::= '<module name>!<routine name>[!<misc info>]' 

рдЗрд╕ рдмрд╛рд╣рд░реА рдирд╛рдо рдЦрдВрдб рдХрд╛ рддрд░реНрдХ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ рдЬреЛ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕реНрдерд╛рди рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред рдпреВрдбреАрдЖрд░ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП, рд╡рд┐рднрд╛рдЬрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдпрд╣ рд░реЗрдЦрд╛ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо, рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдирд╛рдо рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИред рдПрдХ рд╡рд┐рд╕реНрдордпрд╛рджрд┐рдмреЛрдзрдХ рдЪрд┐рд╣реНрди (!) рдПрдХ рд╡рд┐рднрд╛рдЬрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдЗрдВрдЬрди рдЦрдВрдб рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЬрди рдХрд╛ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред рдлрд╛рдпрд░рдмрд░реНрдб рдпреВрдбреАрдЖрд░ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдВрдХрд▓рд┐рдд рднрд╛рд╖рд╛рдУрдВ (рд╕реА, рд╕реА ++, рдкрд╛рд╕реНрдХрд▓) рдореЗрдВ рд▓рд┐рдЦреЗ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реИред рдЬрд╛рд╡рд╛ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ рдЗрдВрдЬрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред


рдХреАрд╡рд░реНрдб рдПрдПрд╕ рдХреЗ рдмрд╛рдж, рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ (рдкреНрд░рдХреНрд░рд┐рдпрд╛, рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рдЯреНрд░рд┐рдЧрд░) рдХрд╛ "рд╢рд░реАрд░", рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ SQL рдХреНрд╡реЗрд░реА рдЖрдкрдХреЗ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдмрд╛рд╣рд░реА рдбреЗрдЯрд╛рдмреЗрд╕ рдпрд╛ рдХрд┐рд╕реА рднрд╛рд╖рд╛ рдореЗрдВ рдкрд╛рда рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред


рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдп


рд╡рд╛рдХреНрдп-рд╡рд┐рдиреНрдпрд╛рд╕
 {CREATE [OR ALTER] | RECREATE} FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] <inparam> ::= <param_decl> [{= |DEFAULT} <value>] <value> ::= {literal | NULL | context_var} <param_decl> ::= paramname <type> [NOT NULL] [COLLATE collation] <extname> ::= '<module name>!<routine name> [!<misc info>]' <type> ::= <datatype> | [TYPE OF] domain | TYPE OF COLUMN rel.col <datatype> ::= {SMALLINT | INT[EGER] | BIGINT} | BOOLEAN | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision [, scale])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size)] [CHARACTER SET charset] | {NCHAR |NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size)] | BLOB [SUB_TYPE {subtype_num | subtype_name}] [SEGMENT SIZE seglen] [CHARACTER SET charset] | BLOB [(seglen [, subtype_num])] 

рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдХрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 ALTER FUNCTION funcname [(<inparam> [, <inparam> ...])] RETURNS <type> [COLLATE collation] [DETERMINISTIC] EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] <extname> ::= '<module name>!<routine name>[!<misc info>]' 

рдЖрдк DROP FUNCTION рдХрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 DROP FUNCTION funcname 

рдПрдХ рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдХреБрдЫ рдкреИрд░рд╛рдореАрдЯрд░
рдкреИрд░рд╛рдореАрдЯрд░рд╡рд┐рд╡рд░рдг
funcnameрд╕рдВрдЧреНрд░рд╣реАрдд рдХрд╛рд░реНрдп рдХрд╛ рдирд╛рдоред 31 рдмрд╛рдЗрдЯ рддрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
inparamрдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рд╡рд┐рд╡рд░рдгред
рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдордмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо рдЬрд┐рд╕рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рд╕реНрдерд┐рдд рд╣реИред
рдирд┐рдпрдорд┐рдд рдирд╛рдордмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЖрдВрддрд░рд┐рдХ рдирд╛рдоред
рдЬрд╛рдирдХрд╛рд░реАрдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ
рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдХрд╛рд░реНрдпред
рдЗрдВрдЬрдирдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЬрди рдХрд╛ рдирд╛рдоред рдЖрдорддреМрд░ рдкрд░ рдирд╛рдо рдпреВрдбреАрдЖрд░ рд╣реИред
extbodyрд╢рд░реАрд░ рдПрдХ рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдп рд╣реИред рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдпреВрдбреАрдЖрд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣рд╛рдВ рд╣рдо рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдирд┐рдпрдорд┐рдд PSQL рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЕрдиреБрдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ SQL рднрд╛рд╖рд╛ рдЧрд╛рдЗрдб рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрддреЗ рд╣реИрдВред


рддреАрди рддрд░реНрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп


 create function sum_args ( n1 integer, n2 integer, n3 integer ) returns integer external name 'udrcpp_example!sum_args' engine udr; 

рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди udrcpp_example рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИред рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░, sum_args рдирд╛рдо рдХреЗ рддрд╣рдд рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкрдВрдЬреАрдХреГрдд рд╣реИред рдПрдХ рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди UDR рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред


рдЬрд╛рд╡рд╛ рдлрдВрдХреНрд╢рди


 create or alter function regex_replace ( regex varchar(60), str varchar(60), replacement varchar(60) ) returns varchar(60) external name 'org.firebirdsql.fbjava.examples.fbjava_example.FbRegex.replace( String, String, String)' engine java; 

рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди org.firebirdsql.fbjava.examples.fbjava_example.FbRegex рд╡рд░реНрдЧ рдХреЗ рд╕реНрдЯреИрдЯрд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╣реИред рдПрдХ рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдЬрд╛рд╡рд╛ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред


рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ


рд╡рд╛рдХреНрдп-рд╡рд┐рдиреНрдпрд╛рд╕
 {CREATE [OR ALTER] | RECREATE} PROCEDURE procname [(<inparam> [, <inparam> ...])] RETURNS (<outparam> [<outparam> ...]) EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] <inparam> ::= <param_decl> [{= | DEFAULT} <value>] <outparam> ::= <param_decl> <value> ::= {literal | NULL | context_var} <param_decl> ::= paramname <type> [NOT NULL] [COLLATE collation] <extname> ::= '<module name>!<routine name>[!<misc info>]' <type> ::= <datatype> | [TYPE OF] domain | TYPE OF COLUMN rel.col <datatype> ::= {SMALLINT | INT[EGER] | BIGINT} | BOOLEAN | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision [,scale])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size)] [CHARACTER SET charset] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size)] | BLOB [SUB_TYPE {subtype_num | subtype_name}] [SEGMENT SIZE seglen] [CHARACTER SET charset] | BLOB [(seglen [, subtype_num])] 

рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕рднреА рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╡рд┐рд╡рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 ALTER PROCEDURE procname [(<inparam> [, <inparam> ...])] RETURNS (<outparam> [, <outparam> ...]) EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] 

рдЖрдк DROP PROCEDURE рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 DROP PROCEDURE procname 

рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдХреБрдЫ рдкреИрд░рд╛рдореАрдЯрд░
рдкреИрд░рд╛рдореАрдЯрд░рд╡рд┐рд╡рд░рдг
funcnameрд╕рдВрдЧреНрд░рд╣рд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдирд╛рдоред 31 рдмрд╛рдЗрдЯ рддрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
inparamрдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рд╡рд┐рд╡рд░рдгред
outparamрдЖрдЙрдЯрдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рд╡рд┐рд╡рд░рдгред
рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдордмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реНрдерд┐рдд рд╣реИред
рдирд┐рдпрдорд┐рдд рдирд╛рдордмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЖрдВрддрд░рд┐рдХ рдирд╛рдоред
рдЬрд╛рдирдХрд╛рд░реАрдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ
рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ред
рдЗрдВрдЬрдирдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЬрди рдХрд╛ рдирд╛рдоред рдЖрдорддреМрд░ рдкрд░ рдирд╛рдо рдпреВрдбреАрдЖрд░ рд╣реИред
extbodyрдПрдХ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╢рд░реАрд░ред рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдпреВрдбреАрдЖрд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣рд╛рдВ рд╣рдо рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдирд┐рдпрдорд┐рдд PSQL рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЕрдиреБрдкрд╛рд▓рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ SQL рднрд╛рд╖рд╛ рдЧрд╛рдЗрдб рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрддреЗ рд╣реИрдВред


 create procedure gen_rows_pascal ( start_n integer not null, end_n integer not null ) returns ( result integer not null ) external name 'pascaludr!gen_rows' engine udr; 

рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд╛рд╕реНрдХрд▓рдбреНрд░рд┐рдб рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИред рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░, рдкреНрд░рдХреНрд░рд┐рдпрд╛ gen_rows рдирд╛рдо рдХреЗ рддрд╣рдд рдкрдВрдЬреАрдХреГрдд рд╣реИред рдПрдХ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдпреВрдбреАрдЖрд░ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред


 create or alter procedure write_log ( message varchar(100) ) external name 'pascaludr!write_log' engine udr; 

рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд╛рд╕реНрдХрд▓рдбреНрд░рд┐рдб рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИред рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░, рдкреНрд░рдХреНрд░рд┐рдпрд╛ write_log рдирд╛рдо рдХреЗ рддрд╣рдд рдкрдВрдЬреАрдХреГрдд рд╣реИред рдПрдХ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдпреВрдбреАрдЖрд░ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред


 create or alter procedure employee_pgsql ( -- Firebird 3.0.0 has a bug with external procedures without parameters dummy integer = 1 ) returns ( id type of column employee.id, name type of column employee.name ) external name 'org.firebirdsql.fbjava.examples.fbjava_example.FbJdbc .executeQuery()!jdbc:postgresql:employee|postgres|postgres' engine java as 'select * from employee'; 

рдлрдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреНрд▓рд╛рд╕ рдХреЗ рд╕реНрдЯреИрдЯрд┐рдХ рдлрдВрдХреНрд╢рди рдПрдХреНрдЬрд╝реАрдХреНрдпреВрдЯрд┐рд╡рд┐рдЯ рдореЗрдВ рд╣реИ
org.firebirdsql.fbjava.examples.fbjava_example.FbJdbc ред рд╡рд┐рд╕реНрдордпрд╛рджрд┐рдмреЛрдзрдХ рдмрд┐рдВрджреБ (!) рдХреЗ рдмрд╛рдж, рд╕реВрдЪрдирд╛ рдЬреЗрдбреАрдмреАрд╕реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдмрд╛рд╣рд░реА рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЬреБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рдд рд╣реИред рдПрдХ рдмрд╛рд╣рд░реА рдлрд╝рдВрдХреНрд╢рди рдЬрд╛рд╡рд╛ рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдВ, рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ "рдирд┐рдХрд╛рдп" рдХреЗ рд░реВрдк рдореЗрдВ, рдбреЗрдЯрд╛ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ SQL рдХреНрд╡реЗрд░реА рдкрд╛рд╕ рдХреА рдЬрд╛рддреА рд╣реИред


рдЯрд┐рдкреНрдкрдгреА

рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдПрдХ рд╕реНрдЯрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдЕрдкреНрд░рдпреБрдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдлрд╛рдпрд░рдмрд░реНрдб 3.0 рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдмрдЧ рд╣реИред

рдкреИрдХреЗрдЬ рдХреЗ рдЕрдВрджрд░ рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдкреНрд▓реЗрд╕рдореЗрдВрдЯ


PSQL рдкреИрдХреЗрдЬ рдореЗрдВ рдкрд░рд╕реНрдкрд░ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рдореВрд╣ рдХреЛ рд░рдЦрдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдкреИрдХреЗрдЬ рдореЗрдВ рдмрд╛рд╣рд░реА рдФрд░ рдирд┐рдпрдорд┐рдд PSQL рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдФрд░ рдХрд╛рд░реНрдп рджреЛрдиреЛрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


рд╡рд╛рдХреНрдп-рд╡рд┐рдиреНрдпрд╛рд╕
 {CREATE [OR ALTER] | RECREATE} PACKAGE package_name AS BEGIN [<package_item> ...] END {CREATE | RECREATE} PACKAGE BODY package_name AS BEGIN [<package_item> ...] [<package_body_item> ...] END <package_item> ::= <function_decl>; | <procedure_decl>; <function_decl> ::= FUNCTION func_name [(<in_params>)] RETURNS <type> [COLLATE collation] [DETERMINISTIC] <procedure_decl> ::= PROCEDURE proc_name [(<in_params>)] [RETURNS (<out_params>)] <package_body_item> ::= <function_impl> | <procedure_impl> <function_impl> ::= FUNCTION func_name [(<in_impl_params>)] RETURNS <type> [COLLATE collation] [DETERMINISTIC] <routine body> <procedure_impl> ::= PROCEDURE proc_name [(<in_impl_params>)] [RETURNS (<out_params>)] <routine body> <routine body> ::= <sql routine body> | <external body reference> <sql routine body> ::= AS   [<declarations>] BEGIN [<PSQL_statements>]   END <declarations> ::= <declare_item> [<declare_item> ...] <declare_item> ::= <declare_var>; | <declare_cursor>; | <subroutine declaration>; | <subroutine implimentation> <subroutine declaration> ::= <subfunc_decl> | <subproc_decl> <subroutine implimentation> ::= <subfunc_impl> | <subproc_impl> <external body reference> ::= EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] <extname> ::= '<module name>!<routine name>[!<misc info>]' 

рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдкреИрдХреЗрдЬ рдХрд╛ рдирд╛рдо, рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░, рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдкреИрдХреЗрдЬ рд╣реЗрдбрд░ рдореЗрдВ рджрд░реНрд╢рд╛рдП рдЧрдП рд╣реИрдВ, рдФрд░ рдкреИрдХреЗрдЬ рдмреЙрдбреА рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╕рдм рдХреБрдЫ рд╕рдорд╛рди рд╣реИ, рд╕рд╛рде рд╣реА рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╕реНрдерд╛рди (EXTERNAL NAME рдЦрдВрдб) рдЗрдВрдЬрди рдХрд╛ рдирд╛рдо, рдФрд░ рд╕рдВрднрд╡рддрдГ рдкреНрд░рдХреНрд░рд┐рдпрд╛ / рдХрд╛рд░реНрдп рдХрд╛ рдирд┐рдХрд╛рдпред


рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдиреЗ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдпреВрдбреАрдЖрд░ рд▓рд┐рдЦрд╛ рд╣реИ, рдЬреЛ рдкреАрд╕реАрдЖрд░рдИ рдХреЗ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ (рдбрд╛рдпрдирд╛рдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА) рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рдФрд░ рдпреВрдбреАрдЖрд░ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдп рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдордиреЗ PSQL рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реА рд╕рднреА рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдФрд░ рд╕рд╛рдорд╛рдиреНрдп PSQL рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рджреЛрдиреЛрдВ рдХреЛ рдорд┐рд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рдирд┐рд░реНрднрд░рддрд╛ рдХреА рдЦреЛрдЬ рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рднреНрд░рдо рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдХрдо рд╕реЗ рдХрдо рд╕рдореВрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИред PSQL рдкреИрдХреЗрдЬ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рддреЗ рд╣реИрдВред


RegExp рдкреИрдХреЗрдЬ
 SET TERM ^; CREATE OR ALTER PACKAGE REGEXP AS BEGIN PROCEDURE preg_match( APattern VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS (Matches VARCHAR(8192)); FUNCTION preg_is_match( APattern VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS BOOLEAN; FUNCTION preg_replace( APattern VARCHAR(8192), AReplacement VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS VARCHAR(8192); PROCEDURE preg_split( APattern VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS (Lines VARCHAR(8192)); FUNCTION preg_quote( AStr VARCHAR(8192), ADelimiter CHAR(10) DEFAULT NULL) RETURNS VARCHAR(8192); END^ RECREATE PACKAGE BODY REGEXP AS BEGIN PROCEDURE preg_match( APattern VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS (Matches VARCHAR(8192)) EXTERNAL NAME 'PCRE!preg_match' ENGINE UDR; FUNCTION preg_is_match( APattern VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS BOOLEAN AS BEGIN RETURN EXISTS( SELECT * FROM preg_match(:APattern, :ASubject)); END FUNCTION preg_replace( APattern VARCHAR(8192), AReplacement VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS VARCHAR(8192) EXTERNAL NAME 'PCRE!preg_replace' ENGINE UDR; PROCEDURE preg_split( APattern VARCHAR(8192), ASubject VARCHAR(8192)) RETURNS (Lines VARCHAR(8192)) EXTERNAL NAME 'PCRE!preg_split' ENGINE UDR; FUNCTION preg_quote( AStr VARCHAR(8192), ADelimiter CHAR(10)) RETURNS VARCHAR(8192) EXTERNAL NAME 'PCRE!preg_quote' ENGINE UDR; END^ SET TERM ;^ 

рдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░


рд╡рд╛рдХреНрдп-рд╡рд┐рдиреНрдпрд╛рд╕
 {CREATE [OR ALTER] | RECREATE} TRIGGER trigname {<relation_trigger_legacy> | <relation_trigger_sql2003> | <database_trigger> | <ddl_trigger> } <external-body> <external-body> ::= EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] <relation_trigger_legacy> ::= FOR {tablename | viewname} [ACTIVE | INACTIVE] {BEFORE | AFTER} <mutation_list> [POSITION number] <relation_trigger_sql2003> ::= [ACTIVE | INACTIVE] {BEFORE | AFTER} <mutation_list> [POSITION number] ON {tablename | viewname} <database_trigger> ::= [ACTIVE | INACTIVE] ON db_event [POSITION number] <ddl_trigger> ::= [ACTIVE | INACTIVE] {BEFORE | AFTER} <ddl_events> [POSITION number] <mutation_list> ::= <mutation> [OR <mutation> [OR <mutation>]] <mutation> ::= INSERT | UPDATE | DELETE <db_event> ::= CONNECT | DISCONNECT | TRANSACTION START | TRANSACTION COMMIT | TRANSACTION ROLLBACK <ddl_events> ::= ANY DDL STATEMENT | <ddl_event_item> [{OR <ddl_event_item>} ...] <ddl_event_item> ::= CREATE TABLE | ALTER TABLE | DROP TABLE | CREATE PROCEDURE | ALTER PROCEDURE | DROP PROCEDURE | CREATE FUNCTION | ALTER FUNCTION | DROP FUNCTION | CREATE TRIGGER | ALTER TRIGGER | DROP TRIGGER | CREATE EXCEPTION | ALTER EXCEPTION | DROP EXCEPTION | CREATE VIEW | ALTER VIEW | DROP VIEW | CREATE DOMAIN | ALTER DOMAIN | DROP DOMAIN | CREATE ROLE | ALTER ROLE | DROP ROLE | CREATE SEQUENCE | ALTER SEQUENCE | DROP SEQUENCE | CREATE USER | ALTER USER | DROP USER | CREATE INDEX | ALTER INDEX | DROP INDEX | CREATE COLLATION | DROP COLLATION | ALTER CHARACTER SET | CREATE PACKAGE | ALTER PACKAGE | DROP PACKAGE | CREATE PACKAGE BODY | DROP PACKAGE BODY | CREATE MAPPING | ALTER MAPPING | DROP MAPPING 

ALTER TRIGGER рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░ рдХреЛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 ALTER TRIGGER trigname { [ACTIVE | INACTIVE] [ {BEFORE | AFTER} {<mutation_list> | <ddl_events>} | ON db_event ] [POSITION number] [<external-body>] <external-body> ::= EXTERNAL NAME <extname> ENGINE <engine> [AS <extbody>] <extname> ::= '<module name>!<routine name>[!<misc info>]' <mutation_list> ::= <mutation> [OR <mutation> [OR <mutation>]] <mutation> ::= { INSERT | UPDATE | DELETE } 

рдЖрдк DROP TRIGGER рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред


рд╡рд╛рдХреНрдп рд░рдЪрдирд╛:


 DROP TRIGGER trigname 

рдкреИрд░рд╛рдореАрдЯрд░рд╡рд┐рд╡рд░рдг
trignameрдЯреНрд░рд┐рдЧрд░ рдХрд╛ рдирд╛рдоред 31 рдмрд╛рдЗрдЯ рддрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
relation_trigger_legacyрдЯреЗрдмрд▓ рдЯреНрд░рд┐рдЧрд░ рдШреЛрд╖рдгрд╛ (рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА)ред
relation_trigger_sql2003SQL-2003 рдорд╛рдирдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдЯреНрд░рд┐рдЧрд░ рдХреА рдШреЛрд╖рдгрд╛ред
database_triggerрдбреЗрдЯрд╛рдмреЗрд╕ рдЯреНрд░рд┐рдЧрд░ рдШреЛрд╖рдгрд╛ред
ddl_triggerрдбреАрдбреАрдПрд▓ рдЯреНрд░рд┐рдЧрд░ рдШреЛрд╖рдгрд╛ред
tablenameрддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдирд╛рдоред
VIEWNAMEрджреЗрдЦрдиреЗ рдХрд╛ рдирд╛рдоред
mutation_listрддрд╛рд▓рд┐рдХрд╛ рдШрдЯрдирд╛рдУрдВ рдХреА рд╕реВрдЪреАред
рдкрд░рд┐рд╡рд░реНрддрдирддрд╛рд▓рд┐рдХрд╛ рдХреА рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХред
db_eventрдПрдХ рдХрдиреЗрдХреНрд╢рди рдпрд╛ рд▓реЗрдирджреЗрди рдХреА рдШрдЯрдирд╛ред
ddl_eventsрдореЗрдЯрд╛рдбреЗрдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдШрдЯрдирд╛рдУрдВ рдХреА рд╕реВрдЪреАред
ddl_event_itemрдореЗрдЯрд╛рдбреЗрдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХред
рд╕рдВрдЦреНрдпрд╛рдЯреНрд░рд┐рдЧрд░ рдХрд╛ рдХреНрд░рдоред 0 рд╕реЗ 32767 рддрдХ
extbodyрдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░ рдХрд╛ рд╢рд░реАрд░ред рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдпреВрдбреАрдЖрд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдордмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо рдЬрд┐рд╕рдореЗрдВ рдЯреНрд░рд┐рдЧрд░ рд╕реНрдерд┐рдд рд╣реИред
рдирд┐рдпрдорд┐рдд рдирд╛рдордмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░ рдЯреНрд░рд┐рдЧрд░ рдХрд╛ рдЖрдВрддрд░рд┐рдХ рдирд╛рдоред
рдЬрд╛рдирдХрд╛рд░реАрдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЯреНрд░рд┐рдЧрд░ рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЬрд╛рдирдХрд╛рд░реАред
рдЗрдВрдЬрдирдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЬрди рдХрд╛ рдирд╛рдоред рдЖрдорддреМрд░ рдкрд░ рдирд╛рдо рдпреВрдбреАрдЖрд░ рд╣реИред

рдпрд╣рд╛рдВ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░реНрд╕ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред


 create database 'c:\temp\slave.fdb'; create table persons ( id integer not null, name varchar(60) not null, address varchar(60), info blob sub_type text ); commit; create database 'c:\temp\master.fdb'; create table persons ( id integer not null, name varchar(60) not null, address varchar(60), info blob sub_type text ); create table replicate_config ( name varchar(31) not null, data_source varchar(255) not null ); insert into replicate_config (name, data_source) values ('ds1', 'c:\temp\slave.fdb'); create trigger persons_replicate after insert on persons external name 'udrcpp_example!replicate!ds1' engine udr; 

рдЯреНрд░рд┐рдЧрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди udrcpp_example рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╣реИред рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░, рдПрдХ рдкреНрд░рддрд┐рдХреГрддрд┐ рдкреНрд░рддрд┐рдХреГрддрд┐ рдирд╛рдо рд╕реЗ рдкрдВрдЬреАрдХреГрдд рд╣реИред рдПрдХ рдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░ UDR рдЗрдВрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред


рдмрд╛рд╣рд░реА рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдВрдХ рдореЗрдВ, рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ ds1 , рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдмрд╛рд╣рд░реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдмрд╛рд╣рд░реА рдЯреНрд░рд┐рдЧрд░ рд╕реЗ replicate_config рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред


рдпреВрдбреАрдЖрд░ рд╕рдВрд░рдЪрдирд╛


рдЕрдм рдкрд╣рд▓рд╛ рдпреВрдбреАрдЖрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рд╣рдо рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рдпреВрдбреАрдЖрд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗред рдПрдХ рдпреВрдбреАрдЖрд░ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рд╕рдВрд░рдЪрдирд╛ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо examples/udr/ рд╕реЗ рдорд╛рдирдХ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ examples/udr/ рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рддред


рдирдП рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ, рдЬрд┐рд╕реЗ рд╣рдо MyUdr рдХрд╣реЗрдВрдЧреЗред рдирддреАрдЬрддрди, рдЖрдкрдХреЛ рдлрд╝рд╛рдЗрд▓ MyUdr.dpr (рдпрджрд┐ рдЖрдкрдиреЗ рдбреЗрд▓реНрдлреА рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рд╣реИ) рдпрд╛ рдлрд╝рд╛рдЗрд▓ MyUdr.lpr (рдпрджрд┐ рдЖрдкрдиреЗ рд▓рд╛рдЬрд░ рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рд╣реИ) рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдм рдореБрдЦреНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗ:


 library MyUdr; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} uses {$IFDEF unix} cthreads, // the c memory manager is on some systems much faster for multi-threading cmem, {$ENDIF} UdrInit in 'UdrInit.pas', SumArgsFunc in 'SumArgsFunc.pas'; exports firebird_udr_plugin; end. 

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ firebird_udr_plugin рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдмрд╛рд╣рд░реА рдпреВрдбреАрдЖрд░ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдкреНрд▓рдЧ-рдЗрди рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реИред рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди UdrInit рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛрдЧрд╛ред


рдЯрд┐рдкреНрдкрдгреА

рдпрджрд┐ рдЖрдк рдирд┐: рд╢реБрд▓реНрдХ рдкрд╛рд╕реНрдХрд▓ рдореЗрдВ рдЕрдкрдирд╛ рдпреВрдбреАрдЖрд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рд╕реНрдХрд▓ рдореЛрдб рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП {$mode objfpc} рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЖрдк {$mode delphi} рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП {$mode delphi} рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдПрдлрдкреАрд╕реА рдФрд░ рдбреЗрд▓реНрдлреА рджреЛрдиреЛрдВ рдореЗрдВ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдореИрдВ {$mode delphi} рдЪреБрдирддрд╛ рд╣реВрдВред

рдирд┐рд░реНрджреЗрд╢ {$H+} рдореЗрдВ рд▓рдВрдмреЗ рддрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдпрджрд┐ рдЖрдк рдкреНрд░рдХрд╛рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ, ansistring рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рди рдХреЗрд╡рд▓ рд╢реВрдиреНрдп-рдЯрд░реНрдорд┐рдиреЗрдЯреЗрдб рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ PChar, PAnsiChar, PWideCharред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд▓рд┐рдирдХреНрд╕ рдФрд░ рдЕрдиреНрдп рдпреВрдирд┐рдХреНрд╕ рдЬреИрд╕реЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рдореЙрдбреНрдпреВрд▓ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ, рдХрд╛рд░реНрдпреЛрдВ рдпрд╛ рдЯреНрд░рд┐рдЧрд░ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ


рдЕрдм UdrInit рдореЙрдбреНрдпреВрд▓ рдЬреЛрдбрд╝реЗрдВ, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:


 unit UdrInit; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses Firebird; //    External Engine  UDR function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; implementation uses SumArgsFunc; var myUnloadFlag: Boolean; theirUnloadFlag: BooleanPtr; function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerFunction(AStatus, 'sum_args', TSumArgsFunctionFactory.Create()); //    //AUdrPlugin.registerProcedure(AStatus, 'sum_args_proc', // TSumArgsProcedureFactory.Create()); //AUdrPlugin.registerProcedure(AStatus, 'gen_rows', TGenRowsFactory.Create()); //    //AUdrPlugin.registerTrigger(AStatus, 'test_trigger', // TMyTriggerFactory.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; initialization myUnloadFlag := false; finalization if ((theirUnloadFlag <> nil) and not myUnloadFlag) then theirUnloadFlag^ := true; end. 

firebird_udr_plugin рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╣рдорд╛рд░реА рдмрд╛рд╣рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ, рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ рдЯреНрд░рд┐рдЧрд░реНрд╕ рдХреЗ рдХрд╛рд░рдЦрд╛рдиреЛрдВ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди, рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдпрд╛ рдЯреНрд░рд┐рдЧрд░ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдкрдирд╛ рдХрд╛рд░рдЦрд╛рдирд╛ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ IUdrPlugin рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:


  • registerFunction тАФ ;
  • registerProcedure тАФ ;
  • registerTrigger тАФ .

, ( ). // SQL. ( ).



. SumArgsFunc. .


SumArgsFunc
 unit SumArgsFunc; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses Firebird; // ********************************************************* // create function sum_args ( // n1 integer, // n2 integer, // n3 integer // ) returns integer // external name 'myudr!sum_args' // engine udr; // ********************************************************* type //        TSumArgsInMsg = record n1: Integer; n1Null: WordBool; n2: Integer; n2Null: WordBool; n3: Integer; n3Null: WordBool; end; PSumArgsInMsg = ^TSumArgsInMsg; //        TSumArgsOutMsg = record result: Integer; resultNull: WordBool; end; PSumArgsOutMsg = ^TSumArgsOutMsg; //       TSumArgsFunction TSumArgsFunctionFactory = class(IUdrFunctionFactoryImpl) //     procedure dispose(); override; {          .        . @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @param(AInBuilder     ) @param(AOutBuilder     ) } procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; {      TSumArgsFunction @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @returns(  ) } function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; override; end; //   TSumArgsFunction. TSumArgsFunction = class(IExternalFunctionImpl) //      procedure dispose(); override; {      execute             .        ,   ExternalEngine::getCharSet. @param(AStatus  ) @param(AContext    ) @param(AName   ) @param(AName    ) } procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; {    @param(AStatus  ) @param(AContext    ) @param(AInMsg    ) @param(AOutMsg    ) } procedure execute(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer); override; end; implementation { TSumArgsFunctionFactory } procedure TSumArgsFunctionFactory.dispose; begin Destroy; end; function TSumArgsFunctionFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; begin Result := TSumArgsFunction.Create(); end; procedure TSumArgsFunctionFactory.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TSumArgsFunction } procedure TSumArgsFunction.dispose; begin Destroy; end; procedure TSumArgsFunction.execute(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer); var xInput: PSumArgsInMsg; xOutput: PSumArgsOutMsg; begin //         xInput := PSumArgsInMsg(AInMsg); xOutput := PSumArgsOutMsg(AOutMsg); //     NULL    NULL xOutput^.resultNull := xInput^.n1Null or xInput^.n2Null or xInput^.n3Null; xOutput^.result := xInput^.n1 + xInput^.n2 + xInput^.n3; end; procedure TSumArgsFunction.getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); begin end; end. 

IUdrFunctionFactory. IUdrFunctionFactoryImpl. . , , . .


dispose , . .


setup . , . .


newItem . , . IRoutineMetadata , . PSQL. . TSumArgsFunction .


IExternalFunction. IExternalFunctionImpl .


dispose , . .


.


getCharSet , . , .


execute . , , .


. , , BLOB. BLOB, .


, . , . , , , NULL ( Null ). , , IMessageMetadata. , execute.


. рдХреЗ рд▓рд┐рдП
Null Null
, NULL,



UDR . : . , .. EXECUTE PROCEDURE .


UdrInit firebird_udr_plugin .


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerFunction(AStatus, 'sum_args', TSumArgsFunctionFactory.Create()); //    AUdrPlugin.registerProcedure(AStatus, 'sum_args_proc', TSumArgsProcedureFactory.Create()); //AUdrPlugin.registerProcedure(AStatus, 'gen_rows', TGenRowsFactory.Create()); //    //AUdrPlugin.registerTrigger(AStatus, 'test_trigger', // TMyTriggerFactory.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

рдЯрд┐рдкреНрдкрдгреА

uses SumArgsProc, .

IUdrProcedureFactory. IUdrProcedureFactoryImpl. . , , . .


dispose , . .


setup . , . .


newItem . , . IRoutineMetadata , . PSQL. . TSumArgsProcedure .


SumArgsProc.


SumArgsProc
 unit SumArgsProc; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses Firebird; { ********************************************************** create procedure sp_sum_args ( n1 integer, n2 integer, n3 integer ) returns (result integer) external name 'myudr!sum_args_proc' engine udr; ********************************************************* } type //        TSumArgsInMsg = record n1: Integer; n1Null: WordBool; n2: Integer; n2Null: WordBool; n3: Integer; n3Null: WordBool; end; PSumArgsInMsg = ^TSumArgsInMsg; //        TSumArgsOutMsg = record result: Integer; resultNull: WordBool; end; PSumArgsOutMsg = ^TSumArgsOutMsg; //       TSumArgsProcedure TSumArgsProcedureFactory = class(IUdrProcedureFactoryImpl) //     procedure dispose(); override; {                  . @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @param(AInBuilder     ) @param(AOutBuilder     ) } procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; {      TSumArgsProcedure @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @returns(  ) } function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; override; end; TSumArgsProcedure = class(IExternalProcedureImpl) public //      procedure dispose(); override; {      open             .        ,   ExternalEngine::getCharSet. @param(AStatus  ) @param(AContext    ) @param(AName   ) @param(AName    ) } procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; {    @param(AStatus  ) @param(AContext    ) @param(AInMsg    ) @param(AOutMsg    ) @returns(      nil   ) } function open(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer): IExternalResultSet; override; end; implementation { TSumArgsProcedureFactory } procedure TSumArgsProcedureFactory.dispose; begin Destroy; end; function TSumArgsProcedureFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; begin Result := TSumArgsProcedure.create; end; procedure TSumArgsProcedureFactory.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TSumArgsProcedure } procedure TSumArgsProcedure.dispose; begin Destroy; end; procedure TSumArgsProcedure.getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); begin end; function TSumArgsProcedure.open(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer): IExternalResultSet; var xInput: PSumArgsInMsg; xOutput: PSumArgsOutMsg; begin Result := nil; //         xInput := PSumArgsInMsg(AInMsg); xOutput := PSumArgsOutMsg(AOutMsg); //     NULL    NULL xOutput^.resultNull := xInput^.n1Null or xInput^.n2Null or xInput^.n3Null; xOutput^.result := xInput^.n1 + xInput^.n2 + xInput^.n3; end; end. 

IExternalProcedure. IExternalProcedureImpl .


dispose , . .


getCharSet . , .


open . , , . , nil, . . TSumArgsFunction.execute.



UDR . firebird_udr_plugin .


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerFunction(AStatus, 'sum_args', TSumArgsFunctionFactory.Create()); //    AUdrPlugin.registerProcedure(AStatus, 'sum_args_proc', TSumArgsProcedureFactory.Create()); AUdrPlugin.registerProcedure(AStatus, 'gen_rows', TGenRowsFactory.Create()); //    //AUdrPlugin.registerTrigger(AStatus, 'test_trigger', // TMyTriggerFactory.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

рдЯрд┐рдкреНрдкрдгреА

uses GenRowsProc, .

. , open, .


GenRowsProc
 unit GenRowsProc; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses Firebird, SysUtils; type { ********************************************************** create procedure gen_rows ( start integer, finish integer ) returns (n integer) external name 'myudr!gen_rows' engine udr; ********************************************************* } TInput = record start: Integer; startNull: WordBool; finish: Integer; finishNull: WordBool; end; PInput = ^TInput; TOutput = record n: Integer; nNull: WordBool; end; POutput = ^TOutput; //       TGenRowsProcedure TGenRowsFactory = class(IUdrProcedureFactoryImpl) //     procedure dispose(); override; {          .        . @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @param(AInBuilder     ) @param(AOutBuilder     ) } procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; {      TGenRowsProcedure @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @returns(  ) } function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; override; end; //   TGenRowsProcedure. TGenRowsProcedure = class(IExternalProcedureImpl) public //      procedure dispose(); override; {      open             .        ,   ExternalEngine::getCharSet. @param(AStatus  ) @param(AContext    ) @param(AName   ) @param(AName    ) } procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; {    @param(AStatus  ) @param(AContext    ) @param(AInMsg    ) @param(AOutMsg    ) @returns(      nil   ) } function open(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer): IExternalResultSet; override; end; //      TGenRowsProcedure TGenRowsResultSet = class(IExternalResultSetImpl) Input: PInput; Output: POutput; //       procedure dispose(); override; {      .     SUSPEND.          . @param(AStatus  ) @returns(True        , False   ) } function fetch(AStatus: IStatus): Boolean; override; end; implementation { TGenRowsFactory } procedure TGenRowsFactory.dispose; begin Destroy; end; function TGenRowsFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; begin Result := TGenRowsProcedure.create; end; procedure TGenRowsFactory.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TGenRowsProcedure } procedure TGenRowsProcedure.dispose; begin Destroy; end; procedure TGenRowsProcedure.getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); begin end; function TGenRowsProcedure.open(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer): IExternalResultSet; begin //      NULL    if PInput(AInMsg).startNull or PInput(AInMsg).finishNull then begin POutput(AOutMsg).nNull := True; Result := nil; exit; end; //  if PInput(AInMsg).start > PInput(AInMsg).finish then raise Exception.Create('First parameter greater then second parameter.'); Result := TGenRowsResultSet.create; with TGenRowsResultSet(Result) do begin Input := AInMsg; Output := AOutMsg; //   Output.nNull := False; Output.n := Input.start - 1; end; end; { TGenRowsResultSet } procedure TGenRowsResultSet.dispose; begin Destroy; end; //   True       . //   False       //         //     function TGenRowsResultSet.fetch(AStatus: IStatus): Boolean; begin Inc(Output.n); Result := (Output.n <= Input.finish); end; end. 

open TGenRowsProcedure NULL, NULL, NULL, SELECT, nil.


, , . UDR Firebird. UDR Legacy UDF.


, open , IExternalResultSet. IExternalResultSetImpl .


dispose . .


fetch SELECT. SUSPEND PSQL . , . true, , false , . , .


рдЯрд┐рдкреНрдкрдгреА

Delphi yeild,
 while(...) do { ... yield result; } 


, open, , fetch. ( SELECT FIRST/ROWS/FETCH FIRST SELECT.)


UDR .


Note

C++ . , . .

UdrInit firebird_udr_plugin .


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerFunction(AStatus, 'sum_args', TSumArgsFunctionFactory.Create()); //    AUdrPlugin.registerProcedure(AStatus, 'sum_args_proc', TSumArgsProcedureFactory.Create()); AUdrPlugin.registerProcedure(AStatus, 'gen_rows', TGenRowsFactory.Create()); //    AUdrPlugin.registerTrigger(AStatus, 'test_trigger', TMyTriggerFactory.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

рдЯрд┐рдкреНрдкрдгреА

uses TestTrigger, .

IUdrTriggerFactory. IUdrTriggerFactoryImpl.
.


dispose , . .


setup . , . .


newItem . , . IRoutineMetadata , . PSQL. . TMyTrigger .


TestTrigger.


TestTrigger
 unit TestTrigger; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses Firebird, SysUtils; type { ********************************************************** create table test ( id int generated by default as identity, a int, b int, name varchar(100), constraint pk_test primary key(id) ); create or alter trigger tr_test_biu for test active before insert or update position 0 external name 'myudr!test_trigger' engine udr; } //     NEW.*  OLD.* //      test TFieldsMessage = record Id: Integer; IdNull: WordBool; A: Integer; ANull: WordBool; B: Integer; BNull: WordBool; Name: record Length: Word; Value: array [0 .. 399] of AnsiChar; end; NameNull: WordBool; end; PFieldsMessage = ^TFieldsMessage; //       TMyTrigger TMyTriggerFactory = class(IUdrTriggerFactoryImpl) //     procedure dispose(); override; {          .       . @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @param(AFieldsBuilder     ) } procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AFieldsBuilder: IMetadataBuilder); override; {      TMyTrigger @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @returns(  ) } function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalTrigger; override; end; TMyTrigger = class(IExternalTriggerImpl) //     procedure dispose(); override; {      execute             .        ,   ExternalEngine::getCharSet. @param(AStatus  ) @param(AContext    ) @param(AName   ) @param(AName    ) } procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; {   TMyTrigger @param(AStatus  ) @param(AContext    ) @param(AAction  ( ) ) @param(AOldMsg      :OLD.*) @param(ANewMsg      :NEW.*) } procedure execute(AStatus: IStatus; AContext: IExternalContext; AAction: Cardinal; AOldMsg: Pointer; ANewMsg: Pointer); override; end; implementation { TMyTriggerFactory } procedure TMyTriggerFactory.dispose; begin Destroy; end; function TMyTriggerFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalTrigger; begin Result := TMyTrigger.create; end; procedure TMyTriggerFactory.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AFieldsBuilder: IMetadataBuilder); begin end; { TMyTrigger } procedure TMyTrigger.dispose; begin Destroy; end; procedure TMyTrigger.execute(AStatus: IStatus; AContext: IExternalContext; AAction: Cardinal; AOldMsg, ANewMsg: Pointer); var xOld, xNew: PFieldsMessage; begin // xOld := PFieldsMessage(AOldMsg); xNew := PFieldsMessage(ANewMsg); case AAction of IExternalTrigger.ACTION_INSERT: begin if xNew.BNull and not xNew.ANull then begin xNew.B := xNew.A + 1; xNew.BNull := False; end; end; IExternalTrigger.ACTION_UPDATE: begin if xNew.BNull and not xNew.ANull then begin xNew.B := xNew.A + 1; xNew.BNull := False; end; end; IExternalTrigger.ACTION_DELETE: begin end; end; end; procedure TMyTrigger.getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); begin end; end. 

IExternalTrigger. IExternalTriggerImpl .


dispose , . .


getCharSet . , .


execute . , , () . () IExternalTrigger. ACTION_ . , Firebird . , DDL , , , nil. . , , .


рдЯрд┐рдкреНрдкрдгреА

, , . IMessageMetadata. , . , , /.

, PSQL


  if (:new.B IS NULL) THEN :new.B = :new.A + 1; 


UDR , . NEW OLD.


, , .
:


  • ( Delphi , .. record);


  • IMessageMetadata, / , .



, тАФ , UDR.



. :


 TMyStruct = record <var_1>: <type_1>; <nullIndicator_1>: WordBool; <var_2>: <type_1>; <nullIndicator_2>: WordBool; ... <var_N>: <type_1>; <nullIndicator_N>: WordBool; end; PMyStruct = ^TMyStruct; 

/ ( ). Null- /, NOT NULL. Null- 2 . -1
/ NULL. NULL- NULL, 2- . SQL :


SQLDelphi
BOOLEANBoolean, ByteBool
SMALLINTSmallint
INTEGERInteger
BIGINTInt64
FLOATSingle
DOUBLE PRECISIONDouble
NUMERIC(N, M):
  • 1-4 тАФ Smallint;
  • 5-9 тАФ Integer;
  • 10-18 (3 ) тАФ Int64;
  • 10-15 (1 ) тАФ Double.

10Mред
DECIMAL(N, M):
  • 1-4 тАФ Integer;
  • 5-9 тАФ Integer;
  • 10-18 (3 ) тАФ Int64;
  • 10-15 (1 ) тАФ Double.

10Mред
CHAR(N)array[0тАж M] of AnsiCharM M=NтИЧBytesPerCharтИТ1ред
BytesPerChar тАФ , /. UTF-8 тАФ 4 /, WIN1251 тАФ 1 /.
VARCHAR(N)FbVarChar<N>M M=NтИЧBytesPerCharтИТ1ред
BytesPerChar тАФ , /. UTF-8 тАФ 4 /, WIN1251 тАФ 1 /. Length . Delphi C++,
FbVarChar<N> ,
. .
DATEISC_DATE
TIMEISC_TIME
TIMESTAMPISC_TIMESTAMPISC_TIMESTAMP Firebird.pas, . .
BLOBISC_QUADBLOB , BlobId. BLOB .

 //      VARCHAR(N) // M = N * BytesPerChar - 1 record Length: Smallint; Data: array[0 .. M] of AnsiChar; end; //      TIMESTAMP ISC_TIMESTAMP = record date: ISC_DATE; time: ISC_TIME; end; 


, .


:


 function SUM_ARGS(A SMALLINT, B INTEGER) RETURNS BIGINT .... 


:


 TInput = record A: Smallint; ANull: WordBool; B: Integer; BNull: WordBool; end; PInput = ^TInput; TOutput = record Value: Int64; Null: WordBool; end; POutput = ^TOutput; 

( 3 ):


 function SUM_ARGS(A NUMERIC(4, 2), B NUMERIC(9, 3)) RETURNS NUMERIC(18, 6) .... 


:


 TInput = record A: Smallint; ANull: WordBool; B: Integer; BNull: WordBool; end; PInput = ^TInput; TOutput = record Value: Int64; Null: WordBool; end; POutput = ^TOutput; 

:


 procedure SOME_PROC(A CHAR(3) CHARACTER SET WIN1251, B VARCHAR(10) CHARACTER SET UTF8) .... 

:


 TInput = record A: array[0..2] of AnsiChar; ANull: WordBool; B: record Length: Smallint; Value: array[0..39] of AnsiChar; end; BNull: WordBool; end; PInput = ^TInput; 

IMessageMetadata




IMessageMetadata. /
:


  • /;
  • ;
  • ;
  • BLOB;
  • /;
  • / NULL;
  • ;
  • NULL-.

IMessageMetadata


  1. getCount


     unsigned getCount(StatusType* status) 

    / . , , : 0 <= index < getCount().


  2. getField


     const char* getField(StatusType* status, unsigned index) 

    .


  3. getRelation


     const char* getRelation(StatusType* status, unsigned index) 

    ( ).


  4. getOwner


     const char* getOwner(StatusType* status, unsigned index) 

    .


  5. getAlias


     const char* getAlias(StatusType* status, unsigned index) 

    .


  6. getType


     unsigned getType(StatusType* status, unsigned index) 

    SQL .


  7. isNullable


     FB_BOOLEAN isNullable(StatusType* status, unsigned index) 

    true, NULL.


  8. getSubType


     int getSubType(StatusType* status, unsigned index) 

    BLOB (0 тАФ , 1 тАФ . .).


  9. getLength


     unsigned getLength(StatusType* status, unsigned index) 

    .


  10. getScale


     int getScale(StatusType* status, unsigned index) 

    .


  11. getCharSet


     unsigned getCharSet(StatusType* status, unsigned index) 

    BLOB.


  12. getOffset


     unsigned getOffset(StatusType* status, unsigned index) 

    ( ).


  13. getNullOffset


     unsigned getNullOffset(StatusType* status, unsigned index) 

    NULL .


  14. getBuilder


     IMetadataBuilder* getBuilder(StatusType* status) 

    IMetadataBuilder, .


  15. getMessageLength


     unsigned getMessageLength(StatusType* status) 

    ( ).



IMessageMetadata


IMessageMetadata IRoutineMetadata. , . . рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:


RoutineMetadata
  //       TSumArgsFunction TSumArgsFunctionFactory = class(IUdrFunctionFactoryImpl) //     procedure dispose(); override; {           @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @param(AInBuilder     ) @param(AOutBuilder     ) } procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; {      TSumArgsFunction @param(AStatus  ) @param(AContext    ) @param(AMetadata   ) @returns(  ) } function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; override; end; //   TSumArgsFunction. TSumArgsFunction = class(IExternalFunctionImpl) private FMetadata: IRoutineMetadata; public property Metadata: IRoutineMetadata read FMetadata write FMetadata; public //      procedure dispose(); override; {      execute             .        ,   ExternalEngine::getCharSet. @param(AStatus  ) @param(AContext    ) @param(AName   ) @param(AName    ) } procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; {    @param(AStatus  ) @param(AContext    ) @param(AInMsg    ) @param(AOutMsg    ) } procedure execute(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer); override; end; ........................ { TSumArgsFunctionFactory } procedure TSumArgsFunctionFactory.dispose; begin Destroy; end; function TSumArgsFunctionFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; begin Result := TSumArgsFunction.Create(); with Result as TSumArgsFunction do begin Metadata := AMetadata; end; end; procedure TSumArgsFunctionFactory.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; 

IMessageMetadata getInputMetadata getOutputMetadata IRoutineMetadata. , , getTriggerMetadata.




, IMessageMetadata . IReferenceCounted. getInputMetadata getOutputMetadata 1 , xInputMetadata xOutputMetadata release.

. IMessageMetadata getOffset . .
null , getNullOffset.


IMessageMetadata
 // ........................ procedure TSumArgsFunction.execute(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer); var n1, n2, n3: Integer; n1Null, n2Null, n3Null: WordBool; Result: Integer; resultNull: WordBool; xInputMetadata, xOutputMetadata: IMessageMetadata; begin xInputMetadata := FMetadata.getInputMetadata(AStatus); xOutputMetadata := FMetadata.getOutputMetadata(AStatus); try //        n1 := PInteger(PByte(AInMsg) + xInputMetadata.getOffset(AStatus, 0))^; n2 := PInteger(PByte(AInMsg) + xInputMetadata.getOffset(AStatus, 1))^; n3 := PInteger(PByte(AInMsg) + xInputMetadata.getOffset(AStatus, 2))^; //   null-      n1Null := PWordBool(PByte(AInMsg) + xInputMetadata.getNullOffset(AStatus, 0))^; n2Null := PWordBool(PByte(AInMsg) + xInputMetadata.getNullOffset(AStatus, 1))^; n3Null := PWordBool(PByte(AInMsg) + xInputMetadata.getNullOffset(AStatus, 2))^; //     = NULL,     nullFlag resultNull := True; Result := 0; //     NULL    NULL //       if not(n1Null or n2Null or n3Null) then begin Result := n1 + n2 + n3; //   ,   NULL  resultNull := False; end; PWordBool(PByte(AInMsg) + xOutputMetadata.getNullOffset(AStatus, 0))^ := resultNull; PInteger(PByte(AInMsg) + xOutputMetadata.getOffset(AStatus, 0))^ := Result; finally xInputMetadata.release; xOutputMetadata.release; end; end; 


. .


, . IUdrProcedureFactory, IUdrFunctionFactory IUdrTriggerFactory UDR. UDR firebird_udr_plugin .


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerFunction(AStatus, 'sum_args', TSumArgsFunctionFactory.Create()); //    AUdrPlugin.registerProcedure(AStatus, 'gen_rows', TGenRowsFactory.Create()); //    AUdrPlugin.registerTrigger(AStatus, 'test_trigger', TMyTriggerFactory.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

TSumArgsFunctionFactory IUdrFunctionFactory, TGenRowsFactory IUdrProcedureFactory, TMyTriggerFactory IUdrTriggerFactory.


, . Firebird. , SuperServer , Classic
.


setup newItem IUdrProcedureFactory, IUdrFunctionFactory IUdrTriggerFactory.


  IUdrFunctionFactory = class(IDisposable) const VERSION = 3; procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; end; IUdrProcedureFactory = class(IDisposable) const VERSION = 3; procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; end; IUdrTriggerFactory = class(IDisposable) const VERSION = 3; procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; end; 

, IDisposable, dispose. Firebird , . dispose , , .
IUdrProcedureFactoryImpl , IUdrFunctionFactoryImpl , IUdrTriggerFactoryImpl . .


newItem


newItem , . UDR , .. , . .


. , , , IUdrFunctionFactory . . .


newItem ,
UDR UDR.



 function TSumArgsFunctionFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; begin //     Result := TSumArgsFunction.Create(); end; 

IRoutineMetadata , UDR . UDR. UDR .


  //   TSumArgsFunction. TSumArgsFunction = class(IExternalFunctionImpl) private FMetadata: IRoutineMetadata; public property Metadata: IRoutineMetadata read FMetadata write FMetadata; public ... end; 

setup


setup . IMetadataBuilder, , .
setup, setup DLL , . .


. , SumArgs.


,


 type //        TSumArgsInMsg = record n1: Integer; n1Null: WordBool; n2: Integer; n2Null: WordBool; n3: Integer; n3Null: WordBool; end; PSumArgsInMsg = ^TSumArgsInMsg; //        TSumArgsOutMsg = record result: Integer; resultNull: WordBool; end; PSumArgsOutMsg = ^TSumArgsOutMsg; 

, setup , .


SumArgsFunctionFactory
 { TSumArgsFunctionFactory } procedure TSumArgsFunctionFactory.dispose; begin Destroy; end; function TSumArgsFunctionFactory.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; begin Result := TSumArgsFunction.Create(); end; procedure TSumArgsFunctionFactory.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin //      AInBuilder.setType(AStatus, 0, Cardinal(SQL_LONG) + 1); AInBuilder.setLength(AStatus, 0, sizeof(Int32)); AInBuilder.setType(AStatus, 1, Cardinal(SQL_LONG) + 1); AInBuilder.setLength(AStatus, 1, sizeof(Int32)); AInBuilder.setType(AStatus, 2, Cardinal(SQL_LONG) + 1); AInBuilder.setLength(AStatus, 2, sizeof(Int32)); //      AOutBuilder.setType(AStatus, 0, Cardinal(SQL_LONG) + 1); AOutBuilder.setLength(AStatus, 0, sizeof(Int32)); end; 



SQL Firebird . , SQL NULL. XSQLDA.


 procedure TSumArgsFunction.execute(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer); var xInput: PSumArgsInMsg; xOutput: PSumArgsOutMsg; begin //         xInput := PSumArgsInMsg(AInMsg); xOutput := PSumArgsOutMsg(AOutMsg); //     = NULL,     nullFlag xOutput^.resultNull := True; //     NULL    NULL //       xOutput^.resultNull := xInput^.n1Null or xInput^.n2Null or xInput^.n3Null; xOutput^.result := xInput^.n1 + xInput^.n2 + xInput^.n3; end; 

, , , setup.


 create or alter function FN_SUM_ARGS ( N1 varchar(15), N2 varchar(15), N3 varchar(15)) returns varchar(15) EXTERNAL NAME 'MyUdrSetup!sum_args' ENGINE UDR; 


 select FN_SUM_ARGS('15', '21', '35') from rdb$database 


UDR , UDR. . Delphi 2009, Free Pascal FPC 2.2.


рдЯрд┐рдкреНрдкрдгреА

Free Pascal
Delphi. FPC 2.6.0 Delphi
.


:


  • , , UDR, ;


  • , , UDR, IMessageMetadata.



newItem . IUdrFunctionFactoryImpl , IUdrProcedureFactoryImpl , IUdrTriggerFactoryImpl . :


SimpleFactories
 unit UdrFactories; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses SysUtils, Firebird; type //     TFunctionSimpleFactory<T: IExternalFunctionImpl, constructor> = class (IUdrFunctionFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; override; end; //     TProcedureSimpleFactory<T: IExternalProcedureImpl, constructor> = class (IUdrProcedureFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; override; end; //     TTriggerSimpleFactory<T: IExternalTriggerImpl, constructor> = class (IUdrTriggerFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AFieldsBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalTrigger; override; end; 

setup , , dispose . newItem T .


 implementation { TProcedureSimpleFactory<T> } procedure TProcedureSimpleFactory<T>.dispose; begin Destroy; end; function TProcedureSimpleFactory<T>.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; begin Result := T.Create; end; procedure TProcedureSimpleFactory<T>.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TFunctionFactory<T> } procedure TFunctionSimpleFactory<T>.dispose; begin Destroy; end; function TFunctionSimpleFactory<T>.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; begin Result := T.Create; end; procedure TFunctionSimpleFactory<T>.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TTriggerSimpleFactory<T> } procedure TTriggerSimpleFactory<T>.dispose; begin Destroy; end; function TTriggerSimpleFactory<T>.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalTrigger; begin Result := T.Create; end; procedure TTriggerSimpleFactory<T>.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AFieldsBuilder: IMetadataBuilder); begin end; 

1 , . :


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerFunction(AStatus, 'sum_args', TFunctionSimpleFactory<TSumArgsFunction>.Create()); //    AUdrPlugin.registerProcedure(AStatus, 'gen_rows', TProcedureSimpleFactory<TGenRowsProcedure>.Create()); //    AUdrPlugin.registerTrigger(AStatus, 'test_trigger', TTriggerSimpleFactory<TMyTrigger>.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

. , . newItem . UDR IRoutineMetadata , Firebird, UDR. , , UDR, ,
UDR. , , .


 unit UdrFactories; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses SysUtils, Firebird; type ... //     TExternalFunction = class(IExternalFunctionImpl) Metadata: IRoutineMetadata; end; //     TExternalProcedure = class(IExternalProcedureImpl) Metadata: IRoutineMetadata; end; //     TExternalTrigger = class(IExternalTriggerImpl) Metadata: IRoutineMetadata; end; 

, .


 unit UdrFactories; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses SysUtils, Firebird; type ... //     TExternalFunction = class(IExternalFunctionImpl) Metadata: IRoutineMetadata; end; //     TExternalProcedure = class(IExternalProcedureImpl) Metadata: IRoutineMetadata; end; //     TExternalTrigger = class(IExternalTriggerImpl) Metadata: IRoutineMetadata; end; 

, .


UDR .


 unit UdrFactories; {$IFDEF FPC} {$MODE DELPHI}{$H+} {$ENDIF} interface uses SysUtils, Firebird; type ... //      TFunctionFactory<T: TExternalFunction, constructor> = class (IUdrFunctionFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; override; end; //      TProcedureFactory<T: TExternalProcedure, constructor> = class (IUdrProcedureFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; override; end; //      TTriggerFactory<T: TExternalTrigger, constructor> = class (IUdrTriggerFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AFieldsBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalTrigger; override; end; 

newItem ,
, .


 implementation ... { TFunctionFactory<T> } procedure TFunctionFactory<T>.dispose; begin Destroy; end; function TFunctionFactory<T>.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; begin Result := T.Create; (Result as T).Metadata := AMetadata; end; procedure TFunctionFactory<T>.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TProcedureFactory<T> } procedure TProcedureFactory<T>.dispose; begin Destroy; end; function TProcedureFactory<T>.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalProcedure; begin Result := T.Create; (Result as T).Metadata := AMetadata; end; procedure TProcedureFactory<T>.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder, AOutBuilder: IMetadataBuilder); begin end; { TTriggerFactory<T> } procedure TTriggerFactory<T>.dispose; begin Destroy; end; function TTriggerFactory<T>.newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalTrigger; begin Result := T.Create; (Result as T).Metadata := AMetadata; end; procedure TTriggerFactory<T>.setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AFieldsBuilder: IMetadataBuilder); begin end; 

https://github.com/sim1984/udr-book/blob/master/examples/Common/UdrFactories.pas .


BLOB


BLOB ( BLOB), . , BLOB , . BLOB . BLOB
IBlob .


BLOB , BLOB , BLOB , BLOB .


BLOB , BLOB (), 64 . getSegment IBlob . putSegment IBlob .


BLOB


BLOB
(
LIST).


 create procedure split ( txt blob sub_type text character set utf8, delimiter char(1) character set utf8 = ',' ) returns ( id integer ) external name 'myudr!split' engine udr; 

:


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //    AUdrPlugin.registerProcedure(AStatus, 'split', TProcedureSimpleFactory<TSplitProcedure>.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

, . .


. .


  TInput = record txt: ISC_QUAD; txtNull: WordBool; delimiter: array [0 .. 3] of AnsiChar; delimiterNull: WordBool; end; TInputPtr = ^TInput; TOutput = record Id: Integer; Null: WordBool; end; TOutputPtr = ^TOutput; 

BLOB BLOB, ISC_QUAD .


:


Split
  TSplitProcedure = class(IExternalProcedureImpl) private procedure SaveBlobToStream(AStatus: IStatus; AContext: IExternalContext; ABlobId: ISC_QUADPtr; AStream: TStream); function readBlob(AStatus: IStatus; AContext: IExternalContext; ABlobId: ISC_QUADPtr): string; public //      procedure dispose(); override; procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; function open(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer): IExternalResultSet; override; end; TSplitResultSet = class(IExternalResultSetImpl) {$IFDEF FPC} OutputArray: TStringArray; {$ELSE} OutputArray: TArray<string>; {$ENDIF} Counter: Integer; Output: TOutputPtr; procedure dispose(); override; function fetch(AStatus: IStatus): Boolean; override; end; 

SaveBlobToStream readBlob BLOB. BLOB , тАФ Delphi. OutputArray Counter.


open BLOB . Split . .


TSplitProcedure.open
 function TSplitProcedure.open(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer): IExternalResultSet; var xInput: TInputPtr; xText: string; xDelimiter: string; begin xInput := AInMsg; if xInput.txtNull or xInput.delimiterNull then begin Result := nil; Exit; end; xText := readBlob(AStatus, AContext, @xInput.txt); xDelimiter := TFBCharSet.CS_UTF8.GetString(TBytes(@xInput.delimiter), 0, 4); //        //    //  - /4 SetLength(xDelimiter, 1); Result := TSplitResultSet.Create; with TSplitResultSet(Result) do begin Output := AOutMsg; OutputArray := xText.Split([xDelimiter], TStringSplitOptions.ExcludeEmpty); Counter := 0; end; end; 

рдЯрд┐рдкреНрдкрдгреА

TFBCharSet Firebird.pas.
Firebird.
UTF-8.
FbCharsets.pas

BLOB . BLOB . openBlob IAttachment . BLOB , . ,
( IExternalContext ).


BLOB (), 64 . getSegment IBlob .


TSplitProcedure.SaveBlobToStream
 procedure TSplitProcedure.SaveBlobToStream(AStatus: IStatus; AContext: IExternalContext; ABlobId: ISC_QUADPtr; AStream: TStream); var att: IAttachment; trx: ITransaction; blob: IBlob; buffer: array [0 .. 32767] of AnsiChar; l: Integer; begin try att := AContext.getAttachment(AStatus); trx := AContext.getTransaction(AStatus); blob := att.openBlob(AStatus, trx, ABlobId, 0, nil); while True do begin case blob.getSegment(AStatus, SizeOf(buffer), @buffer, @l) of IStatus.RESULT_OK: AStream.WriteBuffer(buffer, l); IStatus.RESULT_SEGMENT: AStream.WriteBuffer(buffer, l); else break; end; end; AStream.Position := 0; blob.close(AStatus); finally if Assigned(att) then att.release; if Assigned(trx) then trx.release; if Assigned(blob) then blob.release; end; end; 

рдЯрд┐рдкреНрдкрдгреА

, IAttachment , ITransaction IBlob
IReferenceCounted ,
.
1.
release.

SaveBlobToStream BLOB
:


 function TSplitProcedure.readBlob(AStatus: IStatus; AContext: IExternalContext; ABlobId: ISC_QUADPtr): string; var {$IFDEF FPC} xStream: TBytesStream; {$ELSE} xStream: TStringStream; {$ENDIF} begin {$IFDEF FPC} xStream := TBytesStream.Create(nil); {$ELSE} xStream := TStringStream.Create('', 65001); {$ENDIF} try SaveBlobToStream(AStatus, AContext, ABlobId, xStream); {$IFDEF FPC} Result := TEncoding.UTF8.GetString(xStream.Bytes, 0, xStream.Size); {$ELSE} Result := xStream.DataString; {$ENDIF} finally xStream.Free; end; end; 

рдЯрд┐рдкреНрдкрдгреА

Free Pascal
Delphi TStringStream . FPC
,
.

fetch Counter , . . isc_convert_error .


isc_convert_error
 procedure TSplitResultSet.dispose; begin SetLength(OutputArray, 0); Destroy; end; function TSplitResultSet.fetch(AStatus: IStatus): Boolean; var statusVector: array [0 .. 4] of NativeIntPtr; begin if Counter <= High(OutputArray) then begin Output.Null := False; //         isc_random //        Firebird //  isc_convert_error try Output.Id := OutputArray[Counter].ToInteger(); except on e: EConvertError do begin statusVector[0] := NativeIntPtr(isc_arg_gds); statusVector[1] := NativeIntPtr(isc_convert_error); statusVector[2] := NativeIntPtr(isc_arg_string); statusVector[3] := NativeIntPtr(PAnsiChar('Cannot convert string to integer')); statusVector[4] := NativeIntPtr(isc_arg_end); AStatus.setErrors(@statusVector); end; end; inc(Counter); Result := True; end else Result := False; end; 

рдЯрд┐рдкреНрдкрдгреА

isc_random
, .

:


 SELECT ids.ID FROM SPLIT((SELECT LIST(ID) FROM MYTABLE), ',') ids 

рдЯрд┐рдкреНрдкрдгреА

, BLOB
,
.
,
.
fetch .

BLOB


BLOB
BLOB .


рдЯрд┐рдкреНрдкрдгреА

UDF
BLOB / . UDF
blobsaveload.zip

BLOB /


 CREATE PACKAGE BlobFileUtils AS BEGIN PROCEDURE SaveBlobToFile(ABlob BLOB, AFileName VARCHAR(255) CHARACTER SET UTF8); FUNCTION LoadBlobFromFile(AFileName VARCHAR(255) CHARACTER SET UTF8) RETURNS BLOB; END^ CREATE PACKAGE BODY BlobFileUtils AS BEGIN PROCEDURE SaveBlobToFile(ABlob BLOB, AFileName VARCHAR(255) CHARACTER SET UTF8) EXTERNAL NAME 'BlobFileUtils!SaveBlobToFile' ENGINE UDR; FUNCTION LoadBlobFromFile(AFileName VARCHAR(255) CHARACTER SET UTF8) RETURNS BLOB EXTERNAL NAME 'BlobFileUtils!LoadBlobFromFile' ENGINE UDR; END^ 

:


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //  AUdrPlugin.registerProcedure(AStatus, 'SaveBlobToFile', TSaveBlobToFileProcFactory.Create()); AUdrPlugin.registerFunction(AStatus, 'LoadBlobFromFile', TLoadBlobFromFileFuncFactory.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

BLOB , UDR
06.BlobSaveLoad . LoadBlobFromFile :


 interface uses Firebird, Classes, SysUtils; type //    TInput = record filename: record len: Smallint; str: array [0 .. 1019] of AnsiChar; end; filenameNull: WordBool; end; TInputPtr = ^TInput; //    TOutput = record blobData: ISC_QUAD; blobDataNull: WordBool; end; TOutputPtr = ^TOutput; //   LoadBlobFromFile TLoadBlobFromFileFunc = class(IExternalFunctionImpl) public procedure dispose(); override; procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; procedure execute(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer); override; end; //       LoadBlobFromFile TLoadBlobFromFileFuncFactory = class(IUdrFunctionFactoryImpl) procedure dispose(); override; procedure setup(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata; AInBuilder: IMetadataBuilder; AOutBuilder: IMetadataBuilder); override; function newItem(AStatus: IStatus; AContext: IExternalContext; AMetadata: IRoutineMetadata): IExternalFunction; override; end; 

execute TLoadBlobFromFile , .


execute
 procedure TLoadBlobFromFileFunc.execute(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer); const MaxBufSize = 16384; var xInput: TInputPtr; xOutput: TOutputPtr; xFileName: string; xStream: TFileStream; att: IAttachment; trx: ITransaction; blob: IBlob; buffer: array [0 .. 32767] of Byte; xStreamSize: Integer; xBufferSize: Integer; xReadLength: Integer; begin xInput := AInMsg; xOutput := AOutMsg; if xInput.filenameNull then begin xOutput.blobDataNull := True; Exit; end; xOutput.blobDataNull := False; //    xFileName := TEncoding.UTF8.GetString(TBytes(@xInput.filename.str), 0, xInput.filename.len * 4); SetLength(xFileName, xInput.filename.len); //     xStream := TFileStream.Create(xFileName, fmOpenRead or fmShareDenyNone); att := AContext.getAttachment(AStatus); trx := AContext.getTransaction(AStatus); blob := nil; try xStreamSize := xStream.Size; //     () if xStreamSize > MaxBufSize then xBufferSize := MaxBufSize else xBufferSize := xStreamSize; //   blob blob := att.createBlob(AStatus, trx, @xOutput.blobData, 0, nil); //        BLOB   while xStreamSize <> 0 do begin if xStreamSize > xBufferSize then xReadLength := xBufferSize else xReadLength := xStreamSize; xStream.ReadBuffer(buffer, xReadLength); blob.putSegment(AStatus, xReadLength, @buffer[0]); Dec(xStreamSize, xReadLength); end; //  BLOB blob.close(AStatus); finally if Assigned(blob) then blob.release; att.release; trx.release; xStream.Free; end; end; 

BLOB blobId createBlob IAttachment . BLOB , . , ( IExternalContext ).


BLOB, putSegment IBlob , . close .


BLOB


BLOB
, BLOB .
BLOB,
.


Delphi Free Pascal
.
IBlob
/ Blob.


FbBlob, .


BlobHelper
 unit FbBlob; interface uses Classes, SysUtils, Firebird; const MAX_SEGMENT_SIZE = $7FFF; type TFbBlobHelper = class helper for IBlob {   BLOB   @param(AStatus  ) @param(AStream ) } procedure LoadFromStream(AStatus: IStatus; AStream: TStream); {     BLOB @param(AStatus  ) @param(AStream ) } procedure SaveToStream(AStatus: IStatus; AStream: TStream); end; implementation uses Math; procedure TFbBlobHelper.LoadFromStream(AStatus: IStatus; AStream: TStream); var xStreamSize: Integer; xReadLength: Integer; xBuffer: array [0 .. MAX_SEGMENT_SIZE] of Byte; begin xStreamSize := AStream.Size; AStream.Position := 0; while xStreamSize <> 0 do begin xReadLength := Min(xStreamSize, MAX_SEGMENT_SIZE); AStream.ReadBuffer(xBuffer, xReadLength); Self.putSegment(AStatus, xReadLength, @xBuffer[0]); Dec(xStreamSize, xReadLength); end; end; procedure TFbBlobHelper.SaveToStream(AStatus: IStatus; AStream: TStream); var xInfo: TFbBlobInfo; Buffer: array [0 .. MAX_SEGMENT_SIZE] of Byte; xBytesRead: Cardinal; xBufferSize: Cardinal; begin AStream.Position := 0; xBufferSize := Min(SizeOf(Buffer), MAX_SEGMENT_SIZE); while True do begin case Self.getSegment(AStatus, xBufferSize, @Buffer[0], @xBytesRead) of IStatus.RESULT_OK: AStream.WriteBuffer(Buffer, xBytesRead); IStatus.RESULT_SEGMENT: AStream.WriteBuffer(Buffer, xBytesRead); else break; end; end; end; end. 

BLOB, BLOB :


TLoadBlobFromFileFunc.execute
 procedure TLoadBlobFromFileFunc.execute(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer); var xInput: TInputPtr; xOutput: TOutputPtr; xFileName: string; xStream: TFileStream; att: IAttachment; trx: ITransaction; blob: IBlob; begin xInput := AInMsg; xOutput := AOutMsg; if xInput.filenameNull then begin xOutput.blobDataNull := True; Exit; end; xOutput.blobDataNull := False; //    xFileName := TEncoding.UTF8.GetString(TBytes(@xInput.filename.str), 0, xInput.filename.len * 4); SetLength(xFileName, xInput.filename.len); //     xStream := TFileStream.Create(xFileName, fmOpenRead or fmShareDenyNone); att := AContext.getAttachment(AStatus); trx := AContext.getTransaction(AStatus); blob := nil; try //   blob blob := att.createBlob(AStatus, trx, @xOutput.blobData, 0, nil); //     BLOB blob.LoadFromStream(AStatus, xStream); //  BLOB blob.close(AStatus); finally if Assigned(blob) then blob.release; att.release; trx.release; xStream.Free; end; end; 


, , , / . , BLOB.


, IExternalContext execute , open . IExternalContext getAttachment , getTransaction . UDR, , , startTransaction IExternalContext . . , , .. (2PC).


, SELECT JSON. :


 create function GetJson ( sql_text blob sub_type text character set utf8, sql_dialect smallint not null default 3 ) returns returns blob sub_type text character set utf8 external name 'JsonUtils!getJson' engine udr; 

SQL , , . IMessageMetadata . , ,
Firebird.


рдЯрд┐рдкреНрдкрдгреА

JSON .
CHAR, VARCHAR OCTETS NONE BLOB SUB_TYPE BINARY
base64,
JSON.

:


 function firebird_udr_plugin(AStatus: IStatus; AUnloadFlagLocal: BooleanPtr; AUdrPlugin: IUdrPlugin): BooleanPtr; cdecl; begin //   AUdrPlugin.registerFunction(AStatus, 'getJson', TFunctionSimpleFactory<TJsonFunction>.Create()); theirUnloadFlag := AUnloadFlagLocal; Result := @myUnloadFlag; end; 

, :


GetJson
 unit JsonFunc; {$IFDEF FPC} {$MODE objfpc}{$H+} {$DEFINE DEBUGFPC} {$ENDIF} interface uses Firebird, UdrFactories, FbTypes, FbCharsets, SysUtils, System.NetEncoding, System.Json; // ********************************************************* // create function GetJson ( // sql_text blob sub_type text, // sql_dialect smallint not null default 3 // ) returns blob sub_type text character set utf8 // external name 'JsonUtils!getJson' // engine udr; // ********************************************************* type TInput = record SqlText: ISC_QUAD; SqlNull: WordBool; SqlDialect: Smallint; SqlDialectNull: WordBool; end; InputPtr = ^TInput; TOutput = record Json: ISC_QUAD; NullFlag: WordBool; end; OutputPtr = ^TOutput; //   TSumArgsFunction. TJsonFunction = class(IExternalFunctionImpl) public procedure dispose(); override; procedure getCharSet(AStatus: IStatus; AContext: IExternalContext; AName: PAnsiChar; ANameSize: Cardinal); override; {         @param(AValue ) @param(Scale ) @returns(   ) } function MakeScaleInteger(AValue: Int64; Scale: Smallint): string; {       Json @param(AStatus  ) @param(AContext    ) @param(AJson   Json) @param(ABuffer  ) @param(AMeta  ) @param(AFormatSetting     ) } procedure writeJson(AStatus: IStatus; AContext: IExternalContext; AJson: TJsonArray; ABuffer: PByte; AMeta: IMessageMetadata; AFormatSettings: TFormatSettings); {    @param(AStatus  ) @param(AContext    ) @param(AInMsg    ) @param(AOutMsg    ) } procedure execute(AStatus: IStatus; AContext: IExternalContext; AInMsg: Pointer; AOutMsg: Pointer); override; end; 

MakeScaleInteger , writeJson Json . , execute .


TJsonFunction.execute
 procedure TJsonFunction.execute(AStatus: IStatus; AContext: IExternalContext; AInMsg, AOutMsg: Pointer); var xFormatSettings: TFormatSettings; xInput: InputPtr; xOutput: OutputPtr; att: IAttachment; tra: ITransaction; stmt: IStatement; inBlob, outBlob: IBlob; inStream: TBytesStream; outStream: TStringStream; cursorMetaData: IMessageMetadata; rs: IResultSet; msgLen: Cardinal; msg: Pointer; jsonArray: TJsonArray; begin xInput := AInMsg; xOutput := AOutMsg; //      NULL,    NULL if xInput.SqlNull or xInput.SqlDialectNull then begin xOutput.NullFlag := True; Exit; end; xOutput.NullFlag := False; //      xFormatSettings := TFormatSettings.Create; xFormatSettings.DateSeparator := '-'; xFormatSettings.TimeSeparator := ':'; //      blob inStream := TBytesStream.Create(nil); outStream := TStringStream.Create('', 65001); jsonArray := TJsonArray.Create; //      att := AContext.getAttachment(AStatus); tra := AContext.getTransaction(AStatus); stmt := nil; inBlob := nil; outBlob := nil; try //  BLOB   inBlob := att.openBlob(AStatus, tra, @xInput.SqlText, 0, nil); inBlob.SaveToStream(AStatus, inStream); inBlob.close(AStatus); //   stmt := att.prepare(AStatus, tra, inStream.Size, @inStream.Bytes[0], xInput.SqlDialect, IStatement.PREPARE_PREFETCH_METADATA); //     cursorMetaData := stmt.getOutputMetadata(AStatus); //   rs := stmt.openCursor(AStatus, tra, nil, nil, nil, 0); //     msgLen := cursorMetaData.getMessageLength(AStatus); msg := AllocMem(msgLen); try //     while rs.fetchNext(AStatus, msg) = IStatus.RESULT_OK do begin //     JSON writeJson(AStatus, AContext, jsonArray, msg, cursorMetaData, xFormatSettings); end; finally //   FreeMem(msg); end; //   rs.close(AStatus); //  JSON   outStream.WriteString(jsonArray.ToJSON); //  json   blob outBlob := att.createBlob(AStatus, tra, @xOutput.Json, 0, nil); outBlob.LoadFromStream(AStatus, outStream); outBlob.close(AStatus); finally if Assigned(inBlob) then inBlob.release; if Assigned(stmt) then stmt.release; if Assigned(outBlob) then outBlob.release; tra.release; att.release; jsonArray.Free; inStream.Free; outStream.Free; end; end; 

getAttachment getTransaction IExternalContext . BLOB SQL . prepare IAttachment . SQL . IStatement.PREPARE_PREFETCH_METADATA , . getOutputMetadata IStatement .


рдЯрд┐рдкреНрдкрдгреА

getOutputMetadata .
IStatement.PREPARE_PREFETCH_METADATA
.
, .

openCursor ( 2). getMessageLength IMessageMetadata . , .


fetchNext IResultSet . msg IStatus.RESULT_OK , . writeJson , TJsonObject TJsonArray .


, close , Json , , Blob.


writeJson . IUtil , . IMessageMetadata . TJsonObject . . NullFlag, null , Json.


writeJson
 function TJsonFunction.MakeScaleInteger(AValue: Int64; Scale: Smallint): string; var L: Integer; begin Result := AValue.ToString; L := Result.Length; if (-Scale >= L) then Result := '0.' + Result.PadLeft(-Scale, '0') else Result := Result.Insert(Scale + L, '.'); end; procedure TJsonFunction.writeJson(AStatus: IStatus; AContext: IExternalContext; AJson: TJsonArray; ABuffer: PByte; AMeta: IMessageMetadata; AFormatSettings: TFormatSettings); var jsonObject: TJsonObject; i: Integer; FieldName: string; NullFlag: WordBool; pData: PByte; util: IUtil; metaLength: Integer; //  CharBuffer: array [0 .. 35766] of Byte; charLength: Smallint; charset: TFBCharSet; StringValue: string; SmallintValue: Smallint; IntegerValue: Integer; BigintValue: Int64; Scale: Smallint; SingleValue: Single; DoubleValue: Double; BooleanValue: Boolean; DateValue: ISC_DATE; TimeValue: ISC_TIME; TimestampValue: ISC_TIMESTAMP; DateTimeValue: TDateTime; year, month, day: Cardinal; hours, minutes, seconds, fractions: Cardinal; blobId: ISC_QUADPtr; BlobSubtype: Smallint; blob: IBlob; textStream: TStringStream; binaryStream: TBytesStream; att: IAttachment; tra: ITransaction; begin //  IUtil util := AContext.getMaster().getUtilInterface(); //   TJsonObject    //     jsonObject := TJsonObject.Create; for i := 0 to AMeta.getCount(AStatus) - 1 do begin //      FieldName := AMeta.getAlias(AStatus, i); NullFlag := PWordBool(ABuffer + AMeta.getNullOffset(AStatus, i))^; if NullFlag then begin //  NULL    JSON      jsonObject.AddPair(FieldName, TJsonNull.Create); continue; end; //      pData := ABuffer + AMeta.getOffset(AStatus, i); case TFBType(AMeta.getType(AStatus, i)) of // VARCHAR SQL_VARYING: begin //    VARCHAR metaLength := AMeta.getLength(AStatus, i); charset := TFBCharSet(AMeta.getCharSet(AStatus, i)); //  VARCHAR  2  -  charLength := PSmallint(pData)^; //     base64 if charset = CS_BINARY then StringValue := TNetEncoding.Base64.EncodeBytesToString((pData + 2), charLength) else begin //       3  Move((pData + 2)^, CharBuffer, metaLength - 2); StringValue := charset.GetString(TBytes(@CharBuffer), 0, charLength * charset.GetCharWidth) SetLength(StringValue, charLength); end; jsonObject.AddPair(FieldName, StringValue); end; // CHAR SQL_TEXT: begin //    CHAR metaLength := AMeta.getLength(AStatus, i); charset := TFBCharSet(AMeta.getCharSet(AStatus, i)); //     base64 if charset = CS_BINARY then StringValue := TNetEncoding.Base64.EncodeBytesToString((pData + 2), metaLength) else begin //     Move(pData^, CharBuffer, metaLength); StringValue := charset.GetString(TBytes(@CharBuffer), 0, metaLength); charLength := metaLength div charset.GetCharWidth; SetLength(StringValue, charLength); end; jsonObject.AddPair(FieldName, StringValue); end; // FLOAT SQL_FLOAT: begin SingleValue := PSingle(pData)^; jsonObject.AddPair(FieldName, TJSONNumber.Create(SingleValue)); end; // DOUBLE PRECISION // DECIMAL(p, s),  p = 10..15  1  SQL_DOUBLE, SQL_D_FLOAT: begin DoubleValue := PDouble(pData)^; jsonObject.AddPair(FieldName, TJSONNumber.Create(DoubleValue)); end; // INTEGER // NUMERIC(p, s),  p = 1..4 SQL_SHORT: begin Scale := AMeta.getScale(AStatus, i); SmallintValue := PSmallint(pData)^; if (Scale = 0) then begin jsonObject.AddPair(FieldName, TJSONNumber.Create(SmallintValue)); end else begin StringValue := MakeScaleInteger(SmallintValue, Scale); jsonObject.AddPair(FieldName, TJSONNumber.Create(StringValue)); end; end; // INTEGER // NUMERIC(p, s),  p = 5..9 // DECIMAL(p, s),  p = 1..9 SQL_LONG: begin Scale := AMeta.getScale(AStatus, i); IntegerValue := PInteger(pData)^; if (Scale = 0) then begin jsonObject.AddPair(FieldName, TJSONNumber.Create(IntegerValue)); end else begin StringValue := MakeScaleInteger(IntegerValue, Scale); jsonObject.AddPair(FieldName, TJSONNumber.Create(StringValue)); end; end; // BIGINT // NUMERIC(p, s),  p = 10..18  3  // DECIMAL(p, s),  p = 10..18  3  SQL_INT64: begin Scale := AMeta.getScale(AStatus, i); BigintValue := Pint64(pData)^; if (Scale = 0) then begin jsonObject.AddPair(FieldName, TJSONNumber.Create(BigintValue)); end else begin StringValue := MakeScaleInteger(BigintValue, Scale); jsonObject.AddPair(FieldName, TJSONNumber.Create(StringValue)); end; end; // TIMESTAMP SQL_TIMESTAMP: begin TimestampValue := PISC_TIMESTAMP(pData)^; //    - util.decodeDate(TimestampValue.date, @year, @month, @day); util.decodeTime(TimestampValue.time, @hours, @minutes, @seconds, @fractions); //  -    Delphi DateTimeValue := EncodeDate(year, month, day) + EncodeTime(hours, minutes, seconds, fractions div 10); //  -    StringValue := FormatDateTime('yyyy/mm/dd hh:nn:ss', DateTimeValue, AFormatSettings); jsonObject.AddPair(FieldName, StringValue); end; // DATE SQL_DATE: begin DateValue := PISC_DATE(pData)^; //     util.decodeDate(DateValue, @year, @month, @day); //      Delphi DateTimeValue := EncodeDate(year, month, day); //      StringValue := FormatDateTime('yyyy/mm/dd', DateTimeValue, AFormatSettings); jsonObject.AddPair(FieldName, StringValue); end; // TIME SQL_TIME: begin TimeValue := PISC_TIME(pData)^; //     util.decodeTime(TimeValue, @hours, @minutes, @seconds, @fractions); //      Delphi DateTimeValue := EncodeTime(hours, minutes, seconds, fractions div 10); //      StringValue := FormatDateTime('hh:nn:ss', DateTimeValue, AFormatSettings); jsonObject.AddPair(FieldName, StringValue); end; // BOOLEAN SQL_BOOLEAN: begin BooleanValue := PBoolean(pData)^; jsonObject.AddPair(FieldName, TJsonBool.Create(BooleanValue)); end; // BLOB SQL_BLOB, SQL_QUAD: begin BlobSubtype := AMeta.getSubType(AStatus, i); blobId := ISC_QUADPtr(pData); att := AContext.getAttachment(AStatus); tra := AContext.getTransaction(AStatus); blob := att.openBlob(AStatus, tra, blobId, 0, nil); if BlobSubtype = 1 then begin //  charset := TFBCharSet(AMeta.getCharSet(AStatus, i)); //      textStream := TStringStream.Create('', charset.GetCodePage); try blob.SaveToStream(AStatus, textStream); StringValue := textStream.DataString; finally textStream.Free; blob.release; tra.release; att.release end; end else begin //      binaryStream := TBytesStream.Create; try blob.SaveToStream(AStatus, binaryStream); //    base64 StringValue := TNetEncoding.Base64.EncodeBytesToString (binaryStream.Memory, binaryStream.Size); finally binaryStream.Free; blob.release; tra.release; att.release end; end; jsonObject.AddPair(FieldName, StringValue); end; end; end; //     Json   AJson.AddElement(jsonObject); end; 

рдЯрд┐рдкреНрдкрдгреА

TFbType Firebird.pas .
,
FbTypes .

TFBCharSet Firebird.pas .

FbCharsets . ,
,
, , ,
TEncoding ,
Delphi.

CHAR VARCHAR , OCTETS, base64, Delphi. , VARCHAR 2 .


SMALLINT, INTEGER, BIGINT , . getScale IMessageMetadata . 0, , MakeScaleInteger .


DATE, TIME TIMESTAMP decodeDate decodeTime IUtil . - Delphi TDateTime .


BLOB Delphi. BLOB , TBytesStream . base64. BLOB , TStringStream , . BLOB
.


рд╡рд╣ рд╕рдм рд╣реИред UDR Firebird, .

Source: https://habr.com/ru/post/hi455375/


All Articles