Trabajar con Personas, Activas/NoActivas DataProvider

Trabajar con Personas, Activas/NoActivas


.

How To: Examples of Data Providers with Conditions

Learn how to create Data Providers with output with conditions.

In GeneXus X we've incorporated a new type of object called Data Provider. By way of introduction for those who don't know them, Data Providers are declarative objects that replace a certain class of procedures: those that receive an input, perform a process and whose final objective is to return a set of data in a structured format, which means that the focus is placed on the output.

In this way, the format of the Data Provider's output is defined, thus transforming it into a more declarative object than a procedure because the emphasis is on "what" to do instead of "how" to do it.


The basic components of Data Providers are Groups, Elements, Variables, Subgroups and advanced control options for the Groups (Default clause, Paginate clause, NoOutput clause, OutputIfDetail clause and Input clause).

For more details read the Documentation CommunityWiki 

The objective of this How To is to show two interesting examples.

The first one shows that in the groups' Where conditions we can add conditions in which the left side of the comparison can be either an attribute or even variables. 

Let's suppose that we want to obtain a list of employees with their details. In this case, the DP would be as shown below:

EmployeeCollection
{
       EmployeeItem
      {
                    Id = EmployeeId
                    Name = EmployeeDsc
                    Address = EmployeeAddress
       }
}

If we needed to condition the output depending on whether the user is authorized to view this information or not, we could add the following condition:

EmployeeCollection
{
             EmployeeItem
             Where &UsrAut="S" 
             {
                        Id = EmployeeId
                        Name = EmployeeDsc
                        Address = EmployeeAddress
              }
}

In this case, the filter is added to the generated SQL sentence, which would be as follows:

SELECT [EmployeeId], [EmployeeDsc], [EmployeeAddress] FROM [Employee] WITH (NOLOCK) 
WHERE @AV1UsrAut = "S" ORDER BY 
[EmployeeId]

If I wanted to always return this data but display the address to authorized users only, I could write the following: 

EmployeeCollection 
{
           EmployeeItem
          {
                  EmployeeId
                  EmployeeDsc
                  EmployeeAddress [NoOutput]
                  Where &UsrAut="S"
                  {
                            EmployeeAddress = EmployeeAddress;
                            EmployeeSalary = EmployeeSalary;
                   }
           }
}
 
In this case, a select sentence is generated without the filter condition, which is transformed into an IF in the DP source:
 
Select a ejecutar:
SELECT [EmployeeId], [EmployeeDsc], [EmployeeAddress], [EmployeeSalary] 
FROM [Employee] WITH (NOLOCK) 
ORDER BY [EmployeeId]

Y además en el fuente del DP:
if ( AV1UsrAut = "S")
{
Gxm1employee.gxTpr_Employeeaddress = A363Employee ;
Gxm1employee.gxTpr_Employeesalary = A364Employee ;
}

Note: If, instead of a group of attributes (Address, Salary, etc.), we want to filter only one value we can write:
EmployeeAddress = EmployeeAddress if &UsrAut="S"; 

Let's see another interesting example:

Let's suppose that we have an application that handles Clients and Prospects (Clients are in one table and Prospects are in another). We want to write a Data Provider that will return a Collection containing the Active Clients or Prospects. 

The Data Provider will receive as parameter the order of whether to display Clients or Prospects.

Below is one way to write it:

Parm(&FiltrarPor)
 
 
SDTCliProsCollection
{
          SDTCliProsCollectionItem using DSClientesActivos()
          where &FiltrarPor = 'CLIENTE'
          {
                   PartnerId = ClienteId
                   PartnerName = ClienteName
          }
          SDTCliProsCollectionItem using DSProspectsActivos()
          where &FiltrarPor = 'PROSPECT'
          {
                   PartnerId = ProspectId
                   PartnerName = ProspectName
          }
}

DSClientesActivos defines the filter over Clients and DSProspectsActivos does the same in the Prospects table.

Note that this will always execute the two select clauses but will add to the where clause the &FilterBy value received by parameter in the Data Provider (therefore, one of them will return data and the other will not).

This generates the following:

SELECT [ClienteTipo], [ClienteId], [ClienteNombre] FROM [Cliente] WITH (NOLOCK) 
WHERE (@AV4Filtrar = 'CLIENTE') AND 
([ClienteStatus] = "Activo") ORDER BY [ClienteId]

SELECT [ProspectTipo], [ProspectId], [ProspectNombre] FROM [Prospect] WITH (NOLOCK) 
WHERE (@AV4Filtrar = 'PROSPECT') AND 
([ProspectStatus] = "Activo") ORDER BY [ProspectId]

However, we can write the Data Provider as shown below, so that it doesn't always execute the two select clauses, but only the corresponding one according to the  &FiltrarPor parameter (the select to be executed is chosen in the generated source).

SDTCliProsCollection
{
          SDTCliProsCollectionDummy [NoOutput]
          where &FiltrarPor = 'CLIENTE'
          {
                   SDTCliProsCollectionItem using DSClientesActivos()
                   {
                             PartnerId = ClienteId
                             PartnerName = ClienteNombre
                   }
          }
          SDTCliProsCollectionDummy [NoOutput]
          where &FiltrarPor = 'PROSPECT'
          {
                   SDTCliProsCollectionItem using DSProspectActivos()
                   {
                             PartnerId = ProspectId
                             PartnerName = ProspectNombre
                   }
          }

}

Select clause to execute in the event that the DP is invoked with &FiltrarPor = 'CLIENTE':
 
SELECT [ClienteTipo], [ClienteId], [ClienteNombre] FROM [Cliente] WITH (NOLOCK) 
WHERE [ClienteStatus] = "Activo" ORDER BY [ClienteId]
 
Also, in the Data Provider source:
         if ( ( String.CompareOrdinal(AV4Filtrar.TrimEnd(' '), "CLIENTE".TrimEnd(' ') ) == 0 ) )
         {
            AV10DSClie = AV2Cliente ;
            /* Using cursor P001R2 */
            pr_default.execute(0, new Object[] {AV10DSClie});
            while ( (pr_default.getStatus(0) != 101) )
            {
               ………………………. (select con filtro por [ClienteStatus] = "Activo")
            }
            pr_default.close(0);
         }
         if ( ( String.CompareOrdinal(AV4Filtrar.TrimEnd(' '), "PROSPECT".TrimEnd(' ') ) == 0 ) )
         {
            AV12DSPros = AV3Prospec ;
            /* Using cursor P001R3 */
            pr_default.execute(1, new Object[] {AV12DSPros});
            while ( (pr_default.getStatus(1) != 101) )
            {
               ……………………….(select con filtro por [ProspectStatus] = "Activo")
            }
            pr_default.close(1);
         }

 

         this.cleanup();
.
--
Saludos,
gab
@gxsoft

--
Has recibido este mensaje porque estás suscrito al grupo "GeneXus" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a genexus+unsubscribe@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

GeneXus X+ : Reorganization


GeneXus X+ : Reorganization
Database Reorganization cases where a temporary table is created
Official Content

The cases requiring the creation of a temporary table when executing a database reorganization are those that cannot be solved only with SQL statements. The generator used to run the database reorganization will create and execute a conversion program during the reorganization; these reorganizations are detailed here.

You will identify these kind of database reorganizations in the IAR (Impact Analysis Report); for these cases a temporary table will be created and a GeneXus program or SQL statement will be used to copy the data to the new structures.

Each table conversion will generate a <TableName>conversion file detailing the following:

CREATE TABLE [GXA0001] ( .... )  Run conversion program for table <TableName>  DROP TABLE [<TableName>]  CALL sp_rename('[GXA0001]', '<TableName>')  ALTER TABLE [<TableName>] ....

Note: in this case the database reorganization sample is associated to SQLServer, you will notice some differences when executing with other DBMS.
In short the database reorganization does the following:

  • A temporary table GXA0001 is created with the new table structure.
  • A conversion program is executed to populate the temporary structure.
  • The old table "Tablename" is deleted.
  • The temporary table is renamed with the correct "TableName".
  • The table restrictions are set.

The generator will create and execute the conversion program during the database reorganization using the following pattern for each table:

<TableName>conversion.cs for C# generator.
<TableName>conversion.java for Java generator.
<TableName>conversion.rb for Ruby generator.

Samples

1. Adding a BLOB attribute to a transaction (using SQLServer until version X Evolution 2 upgrade 3)

Note: Since version X Evolution 2 Upgrade 3, this reorg has been optimized, and an "Alter table" is used instead of creating a temporal table (see SAC #32631 for more information) 

CREATE TABLE [GXA0001] (    [Transaction1Id]       SMALLINT     NOT NULL,    [Transaction1Num]   SMALLINT     NOT NULL,    [Transaction1Blob]     VARBINARY(MAX)     NOT NULL)    Run conversion program for table Transaction1    DROP TABLE [Transaction1]    CALL sp_rename('[GXA0001]', 'Transaction1')    ALTER TABLE [Transaction1]  ADD     PRIMARY KEY ( [Transaction1Id] )

2. Adding a Longvarchar attribute to a transaction (using SQLServer until version X Evolution 2 Upgrade 3)

Note: Since version X Evolution 2 Upgrade 3, this reorg has been optimized, and an "Alter table" is used instead of creating a temporal table (see SAC #32631 for more information) 

CREATE TABLE [GXA0001] (    [Transaction1Id]     SMALLINT     NOT NULL,    [Transaction1Num]    SMALLINT     NOT NULL,    [Transaction1LongVC] VARCHAR(MAX)     NOT NULL)    INSERT INTO [GXA0001]             ([Transaction1Id],              [Transaction1Num],              [Transaction1LongVC])  SELECT [Transaction1Id],         [Transaction1Num],         ''  FROM   [Transaction1] T1    DROP TABLE [Transaction1]    DROP TABLE [Transaction1]    CALL sp_rename('[GXA0001]', 'Transaction1')    ALTER TABLE [Transaction1]  ADD     PRIMARY KEY ( [Transaction1Id] )

3. Altering the key of the table, when any other field accepts nulls of the DBMS.

When the key of the table Transaction1 wants to be modified (for example changing a N(5) to a N(6)), an alter table cannot be performed. In this case, a temporary table is created, and the data is copied to the temporary table in an optimized way:

INSERT INTO GXA0001 (a, b, c) SELECT a, b, c FROM Transaction1

If the table Transaction1 has any attribute which has Nullable property - Attribute = TRUE, this optimization cannot be done so the copy is done defining a cursor for querying the data from one table (Transaction1) and another cursor for inserting in the other table.

4. The size of a character attribute is changed to a minor one

For example if there is an attribute, and its type is Char(60), and the reorg consists in changing it to Char(40), a temporary table is created. The script is as follows:

CREATE TABLE [GXA0001] (    [TrnCharactersId]          SMALLINT     NOT NULL,    [TrnCharactersChar60To40]  CHAR(40)     NOT NULL)    Run conversion program for table TrnCharacters  DROP TABLE [TrnCharacters]  CALL sp_rename('[GXA0001]', 'TrnCharacters')  ALTER TABLE [TrnCharacters]   ADD     PRIMARY KEY ( [TrnCharactersId] )

Note: This case was optimized since Salto Beta 1 version.

Others

  • Changing the property nullable from yes to no
  • Case of Informix  - when the rgz0005 is given
  • Case of Oracle  - when more than a table is navigated to load data of a table
  • Case of Informix - when the table to be loaded have to navigate itself
--
Saludos,
gab
@gxsoft

--
Has recibido este mensaje porque estás suscrito al grupo "GeneXus" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a genexus+unsubscribe@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

KB Versions

.
.

Knowledge Base Versions

An application life cycle has several milestones called Versions in GeneXus. A Version holds the status of an application at any given time. It may be a read-only version holding a "photo" of the application at any important time during development. Common names for read-only versions are: Sent to QA, Version 1.0 final, Version 2 as installed in customer X. Versions may also represent separate development threads, sample version names in this case may be, for example: Fixes to QA version, Upgrades to Version 1.0 final,  Hot fixes to Version 2 as installed in customer X.

Having versions of an application in a Knowledge Base targets the following scenarios:

  • Separating development threads.

Being able to continue application development while fixing other version(s) without disrupting each other.

  • Analyzing changes between application versions

Easily comparing versions, moving changes from one to another, etc.

  • Restoring to a previously known state

Versions can be used to make a backup of your applications before making "what if" changes.

  • Basic application customization

Even though versions are not the ideal method for customization, they can be used for this purpose in some situations.

A typical development process

Every new Knowledge Base has a default development version. Opening the Knowledge Base Versions tool window shows this default version, which has the name of the Knowledge Base. Development starts on this version, and it continues until you decide that the desired level of functionality and stability has been reached, and it's time to release your work to customers.

Knowledge Base Versions - Default development version

At release time, it is a good idea to make a copy of your application as it is released. This is called "Freezing" a version and the result is a Frozen version. Right clicking on the default version node shows the Freeze option. Selecting the Freeze option prompts you for the name and description that will be assigned to the new Frozen version. Default values are good enough at this time, so let GeneXus create your new Frozen version, "Version 1".

Knowledge Base Versions - First Freeze

Having created a frozen version, you can switch between them (right click on any of them and set it to Active) and perform the following actions:

  • Continue application development on the next release
  • See exactly what was released as of "Version 1"
  • Compare both versions

Fixing the "Version 1" version

The "Version 1" version is a Frozen version. It cannot be changed. If you need to fix it, you must create a new version. Right click on "Version 1" and select the New Version option. Leave the default names and description and create the new version. The new version "Upgrades for Version 1" is an exact copy of what was released on "Version 1".

Knowledge Base Versions - New development version

Now the diagram shows three versions, one of them is Frozen. Set the "Upgrades for Version 1" to active (Set as Active on context menu). From then on, any change you make in objects, or any objects created or removed willgo to "Upgrades for Version 1". Other versions will not be affected.

Knowledge Base Versions - Upgrades for Version 1 Active

When you've made all the fixes to "Upgrades for Version 1", it's time to release. Once again, select the Freeze option on "Upgrades for Version 1" in the context menu. Leave the default names for the new Frozen version.

Knowledge Base Versions - Freeze Upgrades for Version 1

At this time you are able to:

  • Continue application development on the next release
  • See exactly what was released as of "Version 1"
  • Regenerate the application as of "Version 1"
  • Continue adding fixes to "Version 1" (changing "Upgrades to Version 1")
  • See exactly what was released as of "Version 1.1" (fixes for "Version 1")
  • Regenerate the application as of "Version 1.1"
  • Compare any versions

Various fix sets for "Version 1" version

While not desirable, sometimes it is necessary to create a separate development thread just to make specific fixes. The most common example is having two customers experiencing different problems. When the first problem arises, you create the "Upgrades for Version 1" version and fix it as described above. Later, the second problem arises in a different customer. This customer accepts the fix to his or her problem, and nothing but that fix (i.e. you cannot fix the problem in "Upgrades for Version 1" as it already has another fix). The solution to this is to create a new version from "Version 1" (select New Version from the "Version 1" context menu) and fix the new problem in this version.

Knowledge Base Versions - Various development versions for a single frozen version

Note the horizontal line starting on "Version 1" and linked to "Upgrades for Version 1" and "Upgrades 2 for Version 1"). It states that both versions share a common starting point ("Version 1").

Continue application development

After an application is released, work usually begins on a new version. The most common tasks are adding new features, making major changes, and introducing fixes to existing versions. The new version is not started from scratch, so: where are these changes made? In what version? They are made in the default development version, the one at the top (root) of the Knowledge Base Versions Diagram.

The development cycle continues until your application is ready to be released again. To create a new Frozen version, select the Freeze context menu option of the root node and leave the default names.

Knowledge Base Versions - Continue application development

By now you should've already realized how the cycle works: develop -> freeze -> develop -> freeze ... This cycle applies to any Development Version.

Reading the Knowledge Base Versions Diagram

The Knowledge Base Versions Diagram shows the version hierarchy. Each vertical line is a timeline representing a development thread. Earlier versions in each thread are closer to the top of each vertical line. A horizontal line connects versions sharing a common parent Frozen version.

Frozen versions are displayed as light-brown filled rectangles connected to a vertical line. At the top of this line there is always a Development Version.

Development versions are displayed as rounded rectangles connected to one Frozen version. Many Development versions can be connected to a single Frozen one meaning they all share a common source base.

Knowledge Base Versions - Complex KB Versions Diagram

Version naming convention

Versions can have any name you choose, as long as they are not duplicated. Usually, Frozen version have numbers (1, 2, 3, 1.1, 3.2, etc.) and Development ones are named (code name like Yi, Rocha, Solis, etc.).

Frequently Asked Questions

How do I know what version I'm working on?

The current version is displayed in the Preferences and in the Folder View tool windows as shown in the following image.

Knowledge Base Versions - How do I know in what version am I working on

Comparison with previous GeneXus versions

This section is for GeneXus users that are used to working on versions prior to GeneXus X. The concept of Knowledge Base is a bit different in this version.

Each GeneXus X Version should be considered a Knowledge Base in prior GeneXus versions. A GeneXus X Knowledge Base is, therefore, a set of Knowledge Bases of prior GeneXus versions. A couple of examples may help you understand the concept:

If you want toGeneXus XPrior GeneXus versions
Create a copy of your application at a given milestone. For example, at release timeFreeze a versionCopy Knowledge Base directory to a new one
Continue development for the next versionSet the default development version as activeOpen the development Knowledge Base
Fix a released applicationCreate a (development) Version from the corresponding Frozen one and set it as activeCopy the previous backup directory to a new one
Make a new, separate fix, for released applicationCreate another (development) Version from the corresponding Frozen one and set it as activeCopy the previous backup directory to a new one

 

See Also

Version Properties



--
Saludos,
gab
@gxsoft

--
Has recibido este mensaje porque estás suscrito al grupo "GeneXus" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a genexus+unsubscribe@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Images BLOB, GeneXus





Blob data type
Official Content

The Blob data type allows you to store images, spreadsheets, videos, audio files, and any other type of documents in the database, taking advantage of the different integrity and control mechanisms provided by the DMBS.

There is a way to save blob fields automatically in the database using a web interface (web transaction). There is also an easy way to display a blob field in the web form: a File Upload User control control is generated, and, optionally, an embedded window in which the content (image, video, etc) is shown. 

Note: Using  BlobFile data type instead of Blob data type, the data can be stored using any external storage

Summary:

Display advantages

A blob in the web form can be visualized automatically as an image, video, audio, document, etc, depending on the content of the blob field. It can be displayed as a link, to allow the user to click on it and display the blob, or it can be shown embedded in the web form.

Maintenance advantages

To insert or update blob fields in the database, a file selection dialog appears, which enables the end user to browse the file system structure of the client PC (where the Internet browser is running). The process of uploading the file is then automatic. The user chooses a file that will be uploaded to the server and saved in the database.
The file selection dialog is shown by clicking a "browse" button associated to an edit control in which the selected file is loaded. This is known as an "upload control", and it's shown in the following image:

blob image

And in runtime you will see:

blob runtime

The file selected is uploaded temporarily to a directory in the web server, and then, on the next POST (when the user confirms the transaction) it is saved in the database.

When the blob stores heterogeneous types of files

In some cases, it is necessary to work with different types of files, for example, the same database field contains Word documents, photographs in JPG and GIF format, and video files.

As a result, in some cases, it may be necessary to capture and save the extension of the files while uploading them, so this knowledge is available when you download the same files.

Having the file extension helps in many cases in which the Internet navigator need to know the file format in order to display it, or in cases in which the WebServer prohibits uploading files without extension.

There is a way of automatically capturing the Name and Extension of the file that is being uploaded. This information will also be used when the file is downloaded.

The main goal is to be able to run the application in servers that have a maximum level of security and don't allow uploading files without extension.

In sum, you have two alternatives if you want to keep heterogeneous files in the same field of the table (docs, jpgs, xmls, etc):
 
  1. Define the blob as it is. When the file is uploaded and downloaded, a temporary file without extension will be saved in the file system of the WebServer. When it is downloaded, as the file has no extension, it may be necessary to assign a content type (*) to it, in order to give the navigator a hint aboutthe file's format. Some navigators (like IE) don't need that hint.
  2. If you have a WebServer with very strict security policies (like Windows 2003 server using IIS), by default, it won't allow files without extension to be uploaded. In that case it is better to configure the FileTypeAttribute and FileNameAttribute blob properties in order to enable the blob's extension and name to be captured when it is uploaded. The file will be saved temporarily with the corresponding extension. In addition, when downloading (getting) the blob, it will also be saved with this extension, and its original name.
properties image

Let's look at the attribute properties:  

File Type Attribute Property

It is available only for blob type attributes. The possible values for this property are any char or varchar attribute of the same table which the blob attribute belongs to. This property identifies an attribute that holds the extension of a Blob data type attribute. A Blob data type attribute may store files. Those files may all be the same type of files (i.e. Word documents, pictures in a specified format, etc.) or they may be heterogeneous. When working with heterogeneous files you should store the "file type" (extension) in a different attribute (because the extension isn't stored with the blob itself). In other words, the Blob data type attribute stores the file content and the File Type Attribute stores the file type (or extension).

Every time the Blob data type attribute is assigned (either in the user interface or by an assignment command) the value of the FileTypeAttribute is also automatically assigned. That is to say that the FileTypeAttribute is assigned when you upload a blob from a Web Interface (a Web Transaction), a procedure or a Business Component in a batch mode (from a procedure).

The default value is (none), stating that no attribute holds the file type.

Constraints on the FileTypeAttribute:

  • It must be Character or VarChar (not Long Varchar) data type.
  • It must belong to the same table that the referencing attribute belongs to.
  • It should not be a formula.
  • It cannot be used as the FileTypeAttribute or FileNameAttribute of any other Blob attribute.

Note: If the FileTypeAttribute property is assigned with a value, the corresponding attribute assigned to this property cannot be explicitly modified through a web transaction.

File Type Runtime property

As we've already explained the FileType property, let's now look at the FileType runtime property. You can use it to retrieve the file extension of a blob, or change it dinamically by using the following sintax:

&extension = Attblob.FileType

The FileType property returns the actual file extension, when the blob is being uploaded.

For instance, if you have the following rule in a web transaction:

msg('The uploaded file is ' + Attblob.FileName + '.' + Attblob.FileType) if not Attblob.isempty() on aftervalidate;

When uploading the file, Attblob.FileType returns the actual file extension.

When the file is being downloaded, the FileType is obtained from:

1. The FileType property, if it's assigned in the design model.
2. The FileTypeAttribute property of the blob (if it has one).

Otherwise, it returns null.

File Name Attribute Property

 

The FileNameAttribute property identifies an attribute that holds the File Name of a Blob data type attribute. A Blob data type attribute can store files. The attribute stores the file content but not it's original name. You should set this property if you want to keep track of the original file name.

Every time the Blob data type attribute is assigned (either in the user interface or by an assignment command) the value of the FileNameAttribute is also automatically assigned.

The default value is (none), stating that the original file name is lost.

Constraints on the FileNameAttribute:

  • It must be Character or VarChar (not Long Varchar) data type
  • It must belong to the same table that the referencing attribute belongs to.
  • It should not be a formula
  • It cannot be used as the FileTypeAttribute or FileNameAttribute of any other Blob attribute.

Note: When downloading the file, it is temporary saved with its original name (which is taken from the FileNameAttribute), plus a random number. So that each file is given a different name, in order to be able to run the application in multiuser and concurrent environments.

Managing different Content Types

Content Types are a means of identifying web pages, images, and multimedia files on the Web and in email messages. They allow web browsers and email clients to display content in a correct and safe way. In the case of blobs, it may be necessary to set their Content Type, especially for certain kind of files, or for certain Internet navigators. Commonly used content types include text/html, image/jpeg, model/vrml, video/quicktime, etc.

It's important to note that GeneXus automatically generates the corresponding Content Type of each blob, based on the extension it has. But there are ways to change this Content Type, if the user wants to.

There are two ways to do this in GeneXus:

ContentType property (design and runtime control property)

content type file type property

ContentType Property

It indicates the content type that should be associated with the Blob. For example, the content type of .wav documents is generally audio/wav, for an .xml file it's text/xml, etc.

The Content Type depends on the browser, and that's why the GeneXus user is given the possibility of setting it programmatically. However, the corresponding Content Type is actually determined at runtime by the generated program.
That is to say, in most cases you only need to set the File Type properties or nothing at all, if the blob has a FileTypeAttribute associated to it. This is because GeneXus automatically determines the Content Type, from this information.

The ContentType Property should be used when the extension doesn't allow unique identification of the Content Type, or when the GeneXus user wants to set it depending on the end user's browser.

Retrieving the name of the file

You can query the name of the file by using the FileName property (runtime property). This is a ReadOnly property, which allows you to know the name of the file associated to a blob. When uploading the file, it returns the name of the file which is being uploaded. For instance, if you have the following rule in a web transaction:

msg('The uploaded file is ' + Attblob.FileName + '.' + Attblob.FileType) if not Attblob.isempty() on aftervalidate;

When uploading the file, Attblob.FileName returns the actual file name. On the contrary, when downloading a file (if it is in a webpanel, for instance), the value returned by the property is based on the value stored in the FileNameAttribute exclusively. This is because the blob by itself doesn't store any information other than the binary file. It doesn't store the extension or the name of the file.

Display control properties

Width / Height

Determines the width / height of the blob control in the form. 

Display

It indicates the way the blob content is going to be displayed in the form. It's available in design model and at runtime. The possible values are:
 

blob runtime

blob link

Note: 

If you define a different value than 0 or 1 (only in runtime) in the property, the blob will not be displayed either Inline or Link.

LinkTarget

When the display property is set to "Link", by this property you can choose to show the blob content in a separate window.
For example: blobatt.linktarget = '_blank'

Parameters

When the display property is set to "Inline", and the blob content can't be managed by the Internet browser without providing additional information to it, the Parameters property has to be used to provide the necessary information to the browser.
For example, if you want to display a video in mpg format, in the IE (Internet Explorer), you have to have the following settings:

(This example runs in Windows Media Player)
blobatt.parameters = '<param name="Filename" value="' + pathtourl( blobatt) + '">' +
'<param name="AutoStart" value="True">' +
'<param name="ShowControls" value="True">' +
'<param name="ShowStatusBar" value="True">' +
'<param name="ShowDisplay" value="False">' +
'<param name="AutoRewind" value="True">'

Note: The Internet browsers need to know which application to use to display certain type of files. That is what the ContentType property is for. For example, in the case of IE, when the content is .mpg, the ContentType should not be video/mpg (as it would be by default), but application/x-mplayer2. In these special cases, the ContentType refers to the application which should show the content instead of the real content type of the file.

Environment Properties

Blob Local Storage Path

This environment property is used to set the web server path where files are temporarily saved when retrieved from the database. That is to say, when you Get data, a temporary file is saved in the Blob Local Storage Path. The extension of the saved file depends on the value of the Blob property called File Type.

The Blob Local Storage Path must be accessible from the virtual directory (ie, if the virtual directory is C:\resin-2.0.2\webapps\test an acceptable value for the property would be: C:\resin-2.0.2\webapps\test\resources\rtrepository).

Temporary Media Directory

This environment property is used to set the web server path where files are temporarily saved when loaded in the database. That is to say, when a Blob is added or updated, it is temporarily saved in this directory.

The Temporary Media Directory must be accessible from the virtual directory.

Example

Let's see an example in which we use the Blob data type. We create a Country transaction, with attributes CountryId, CountryName, CountryFlag, and CountryAnthem. The latter two are of the blob type, so that we can store the flag of the country, and its national anthem. 

BlobDataTypeCountryTRN

We now go to the properties of the blob-type attributes, and in the File Type property, we set png for CountryFlag, and wav for CountryAnthem:

FileTypePNG  FileTypeWav

Finally, we press F5, and in the Country transaction we insert the country Uruguay, along with its flag and national anthem:

CountryUruguayBlob

Notes:

Functions

PathToURL function

Appendix

I. In general, Internet Explorer doesn't respect the Content Type returned by web servers and uses a variety of strategies to automatically detect the content type of files.

This means that different browsers have different behaviors. For example, when a blob field is displayed as a download (link), and a Content Type is specified, IE determines how to display the blob in the form by using the above strategies. Therefore, the Content Type is only considered as a hint for the browser.
This doesn't happen with Mozilla, which always considers the specified Content Type. Therefore, we recommend reading the corresponding documentation so as to know beforehand what the expected behavior is for the application.

Our tests produced the following results:

1. When the blob is displayed as a link, the Content Type is ignored by IE. It has its own rules for identifying the content type and ignores the one specified by the user. The same happens with Netscape. Consequently, the file will be correctly displayed in the HTML only if the file type can be identified by the browser. To solve this, give the file an extension through the FileType property when saving it temporarily. This problem doesn't exist in Mozilla FireFox.

2. If you set the FileType property, the blob is temporarily saved in the server with an extension. In this case, the web server decides how to display the content through MIME Types, so the specified Content Type is ignored. Blobs that are Word documents, for example, are correctly viewed only if they are displayed as links, and they have an associated extension or "FileType" (the same happens with Excel worksheets).

3. In some cases, when the blob display is Inline and has an associated extension (File Type), IE can't display the content, while Netscape and Mozilla try to download it (for example, it happens with .doc, .xls, .pdf).

4. If the display is Inline and you work with File Type or Content Type, IE, Netscape and Mozilla all consider the specified Content Type, except in the case of Word documents and some other exceptions. Some MIME types, like graphics, can be displayed inside the browser. Others, such as word processing documents, require an external helper application in order for them to be displayed.

The following table shows some Content Types which are assigned automatically, given a File Type (an associated extension).

FileTypeContent-Type
 
TXTtext/plain
RTXtext/richtext
HTML/HTMtext/html
XMLtext/xml
AIFaudio/x-aiff
AUaudio/basic
WAVaudio/wav
BMPimage/bmp
GIFimage/gif
JPE/JPEG/JPGimage/jpeg
JFIFimage/pjpeg
TIFimage/tiff
MPEGvideo/mpeg
MOV/QTvideo/quicktime
AVIvideo/x-msvideo
EXEapplication/octet-stream
PSapplication/postscript
PDFapplication/pdf
TGZapplication/x-compressed
PNGimage/x-png
ZIPapplication/x-zip-compressed
GZapplication/x-gzip
DLLapplication/x-msdownload


II. Changing the Temporary Media Directory and Blob Local Storage Path at runtime

You can change the Temporary Media Directory and the Blob Local Storage Path at runtime for the Java generator by changing the client.cfg. For example:
TMPMEDIA_DIR=C:\Program Files\Apache Software Foundation\Tomcat 5.0\webapps\YIBLOB\TempMedia

CS_BLOB_PATH=C:\Program Files\Apache Software Foundation\Tomcat 5.0\webapps\YIBLOB\media

Note

When the blob's content is restricted to images, video or audio, the use of ImageVideo or Audio data types should be considered instead the blob data type.

  • FileType property (design and runtime property)
  • 0: Inline: The blob is displayed in the form, above the upload control.
  • 1: Link: An image is displayed with a link to the Blob.
  • For security reasons, there are two different properties. However, GeneXus users may set them to point to the same physical directory. The Blob Local Storage Path will always be accesible to the user.
  • The application must have read / write permissions for these directories
  • In NET generator, by default, the Temp Media directory and Blob Local Storage path properties are considered to be the WEB folder under the model directory.
  • In Java generator, both directories must exist. That is to say, they are not automatically created by GeneXus.

Scope

ObjectsTransaction objectWeb Panel object
Languages.NET, Java
  

See also

Blobs in Base64



--
Saludos,
gab
@gxsoft

--
Has recibido este mensaje porque estás suscrito al grupo "GeneXus" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a genexus+unsubscribe@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.