PS_APP_HOME introduced in PeopleTools 8.52

Traditionally, a PS_HOME contained both PeopleTools and Application related files. This meant that you had to maintain four different PS_HOME folders for each of you DEV, TST, QA and PROD environments. For customers that use more than one PeopleSoft application (and there are many many), the number of PS_HOMEs multiply and get un-manageable at some point in time.

PeopleTools 8.52 introduces PS_APP_HOME which co-exists with a PS_HOME, ofcourse along with the PS_CFG_HOME. That sounds like a lot of HOMEs ūüėČ What does each of these contain? Simply put, PS_HOME – contains all that your PeopleTools CDs offer, while PS_APP_HOME contains all that your application and language media packs offer. PS_CFG_HOME contains all your application server and process scheduler domain configuration fules.

I personally think that the separation offered by PS_HOME and PS_APP_HOME reduces a lot of administration overhead. And a lot of space too. The separation also tremendously streamlines the application of peopletools patches and promises a shorter time-to-production.

Just that you need to ensure you set PS_APP_HOME to the appropriate environment (DEV/QA etc) before invoking PSADMIN. You would also need to enlist both PS_HOME and PS_APP_HOME in your process scheduler for SQR files, because DDDAUDIT would come from PS_HOME and PER010 from you HR PS_APP_HOME.

Finally, PS_APP_HOME is an optional feature. You could still continue to use PS_HOMEs the traditional way

Write Data Between Table And File in Postgres

Write Data between Table and File

Postgres offers COPY commands for writing table data into text files (ascii or binary) and also write back from these files to postgres table.

The COPY TO command is used to copy the content of a table to a standard text file. If you specify column name of a table, while using COPY TO, the specified fields only will be written to a file. COPY FROM command is used to copy the content of a file to a database table.

Copy Data from Table to File

The following command is used to copy data from table to file.

Syntax
COPY <tablename> [(<column list,...>)] TO {'<filename>'}

where

tablename - Name of the table that we are going to copy
Column List - Column Names of the given table
File Name - Specify the file to which data should be written to

Example

Copy All fields to file

 postgres=#COPY student TO '/tmp/stud1.txt';

The above command will copy all the fields from student table to stud.txt file.

Copy Specified Field Only

postgres=#COPY student(rollno,total,avg) TO '/tmp/stud2.txt';

The above command will copy only specified fields from the student table to the stud.txt file and the file is saved in /tmp/ directory.
OutPut  
Sample Files


Copy Data from File to Table

The following command is used to copy data from File to Table.

Syntax

COPY <tablename> [(<column list,...>)] FROM {'<filename>'}

where

tablename -Name of the table that we are going to copy
Column List - Column Names of the given table
File Name - Specify the file name from which data will be copied to table.

Example
Copy All fields to Table

 postgres=#COPY student FROM '/tmp/stud1.txt';

The above command will copy the file named stud1.txt data to the student table.

Copy Only Speicified fields to Table

 postgres=#COPY student(name,total,avg) FROM '/tmp/stud2.txt'; 

The above command will copy data from the given file to the specified fields in student table.

Output

See More in http://www.postgresql.org/docs/8.1/static/sql-copy.html

Tablespace information in Oracle

Every DBA evolves his/her own style over a period of time. They build handy scripts  to carry out each and every activity in the database, including monitoring jobs, gathering tablespace information etc etc. Here is one particular script that I use to gather free/utilized space information on tablespaces.

SELECT A.TABLESPACE_NAME, A.TOTALSPACE TOTALSPACE,(A.TOTALSPACE - B.FREESPACE) USEDSPACE, B.FREESPACE FREESPACE FROM
 (SELECT TABLESPACE_NAME,SUM/1024/1024/1024 TOTALSPACE FROM DBA_DATA_FILES where TABLESPACE_NAME in (select tablespace_name from dba_segments where segment_name in ('SET OF TABLES T1','T2','T3'.'T4'))GROUP BY TABLESPACE_NAME) A,
 (SELECT TABLESPACE_NAME,SUM/1024/1024/1024 FREESPACE FROM DBA_FREE_SPACE where TABLESPACE_NAME in select tablespace_name from dba_segments where segment_name in ('SET OF TABLES T1','T2','T3'.'T4')) GROUP BY TABLESPACE_NAME) B WHERE A.TABLESPACE_NAME =B.TABLESPACE_NAME ;

Sample Output for the above script will be

TABLESPACE_NAME       TOTALSPACE        USEDSPACE       FREESPACE
GPAPP                                           101                      92.4963989       8.50360107
PSINDEX                                      167                     150.486206       16.5137939

Hope it will be useful for you. Comments are most welcome.

“Appreciation is a wonderful thing:It makes what is excellent in others belong to us as well”

Using Business Event Handlers in Openbravo

All current technologies supports multiple layers in the Application thereby enabling us the advantage and flexibility to separate the Application layer from the Business Layer and similarly separating the Business layer from the Database Layer. Openbravo is built on a MVC Architecture that enables us to separate the data layer, the logic layer and the application layer. But do we use it to the fullest extent? In most of the current solutions, the business logic is done database dependently in Triggers and Procedures. Openbravo has provided an efficient alternate to remove this database dependency.

Business event handler is an efficient alternative to database triggers.Since the business event handlers are written using DAL, it has all the advantages of using DAL and also it becomes database independent. The business event handler gets triggered whenever save, update and delete operations are performed. The event gets triggered even before the object gets into the database because of which the changes will be committed as a single transaction with all our business logics. The DAL layer uses clean and readable coding which can be used in business event handler. The business event handler uses Weld framework which will automatically detect the all the business event handlers through the using the annotation. This makes very easy for the developers to create the business event handler in a few minutes. Its enough if we just create a DAL file which extends the class EntityPersistenceEventObserver.

package org.openbravo.erpCommon.businessHandler;
import javax.enterprise.event.Observes;
import org.apache.log4j.Logger;
import org.openbravo.base.model.Entity;
import org.openbravo.base.model.ModelProvider;
import org.openbravo.base.model.Property;
import org.openbravo.model.common.businesspartner.BusinessPartner;
import org.openbravo.client.kernel.event.EntityDeleteEvent;
import org.openbravo.client.kernel.event.EntityNewEvent;
import org.openbravo.client.kernel.event.EntityPersistenceEventObserver;
import org.openbravo.client.kernel.event.EntityUpdateEvent;
/**
* Listens to events on the {@link BusinessPartnerHandler} entity.
*
* @author Pandeeswari
*/
public class BusinessPartnerHandler extends EntityPersistenceEventObserver {
private static Entity[] entities = { ModelProvider.getInstance().getEntity(BusinessPartnerHandler.ENTITY_NAME) };
private static Logger log = Logger.getLogger(BusinessPartnerHandler.class);
@Override
protected Entity[] getObservedEntities() {
return entities;
}
public void onUpdate(@Observes
EntityUpdateEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity businessPartnerEntity = ModelProvider.getInstance().getEntity(BusinessPartner.ENTITY_NAME);
String searchKey = ((BusinessPartner) event.getTargetInstance()).getSearchKey();
String name = ((BusinessPartner) event.getTargetInstance()).getName();
final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
event.setCurrentState(name2Property, searchKey + " - " + name);
}
public void onSave(@Observes
EntityNewEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity businessPartnerEntity = ModelProvider.getInstance().getEntity(BusinessPartner.ENTITY_NAME);
String searchKey = ((BusinessPartner) event.getTargetInstance()).getSearchKey();
String name = ((BusinessPartner) event.getTargetInstance()).getName();
final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
event.setCurrentState(name2Property, searchKey + " - " + name);
}
public void onDelete(@Observes
EntityDeleteEvent event) {
if (!isValidEvent(event)) {
return;
}
}
}

The above program appends the searchkey and name of the business partner and updates in the name2 field in business partner whenever the value is inserted or updated. Whenever an action is performed, the getObservedEntities() Method will be called which will return the array of entities that are being observed. In short, it will give the array of entities that has business event handlers. This entity array is used to check if a certain event is targeted for this observer. Say if an entity is being updated. The getObservedEntities() method will give all the observed entities and the method isValidEvent will check whether the entity is an observed entity. If the target entity exists in the list of observed entity, then it will return true. Also the event is automatically captured by @Observes and routed correspondingly to any of the methods onUpdate, onSave, onDelete.

The old and new values of a field can be accessed using OLD and NEW Identifier in database triggers. This can be done in business event handlers using the methods, getPreviousState and getCurrentState method. The method getCurrentState will be available in all the 3 classes EntityUpdateEvent, EntityNewEvent and EntityDeleteEvent whereas the getPreviousState method will be available only in EntityUpdateEvent class. This makes sense because we can get the previous state(old values) only when the record is being updated. Similarly, we can set a new value to a property(field) using the method setCurrentState which will be available in all the 3 classes. Though it is available in all the 3 classes, it is applicable only for new and update event.

final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
Object previousName = event.getPreviousState(name2Property);
Object currentName = event.getCurrentState(name2Property);

When we want to interrupt certain event, we can throw an exception as we raise exception in database triggers. It can be done as follows,

public void onSave(@Observes EntityNewEvent event) {
if (!isValidEvent(event)) {
return;
}
final Entity businessPartnerEntity = ModelProvider.getInstance().getEntity(BusinessPartner.ENTITY_NAME);
String searchKey = ((BusinessPartner) event.getTargetInstance()).getSearchKey();
String name = ((BusinessPartner) event.getTargetInstance()).getName();
if(searchKey != null && name != null) {
final Property name2Property = businessPartnerEntity.getProperty(BusinessPartner.PROPERTY_NAME2);
event.setCurrentState(name2Property, searchKey + " - " + name);
}
else {
String language = OBContext.getOBContext().getLanguage().getLanguage();
ConnectionProvider conn = new DalConnectionProvider(false);
throw new OBException(Utility.messageBD(conn, "C_NullValue", language));
}
}

Leave in your comments about your views on implementing business logics at the database level or at the DAL layer.