#*OEM*
package PowerBuilder::ORCA;
use strict;
use Carp;
require Exporter;
require DynaLoader;
require AutoLoader;
our @ISA = qw(Exporter DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
our %EXPORT_TAGS = ( 'const' => [ qw(
PBORCA_APPLICATION
PBORCA_DATAWINDOW
PBORCA_FUNCTION
PBORCA_MENU
PBORCA_PIPELINE
PBORCA_PROJECT
PBORCA_PROXYOBJECT
PBORCA_QUERY
PBORCA_STRUCTURE
PBORCA_USEROBJECT
PBORCA_WINDOW
PBORCA_P_CODE
PBORCA_MACHINE_CODE
PBORCA_MACHINE_CODE_NATIVE
PBORCA_MACHINE_CODE_16
PBORCA_P_CODE_16
PBORCA_OPEN_SERVER
PBORCA_TRACE_INFO
PBORCA_ERROR_CONTEXT
PBORCA_MACHINE_CODE_OPT
PBORCA_MACHINE_CODE_OPT_SPEED
PBORCA_MACHINE_CODE_OPT_SPACE
PBORCA_MACHINE_CODE_OPT_NONE
PBORCA_FULL_REBUILD
PBORCA_INCREMENTAL_REBUILD
PBORCA_MIGRATE
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'const'} } );
our @EXPORT = qw(
);
our $VERSION = '0.05';
our $AUTOLOAD;
sub AUTOLOAD {
# This AUTOLOAD is used to 'autoload' constants from the constant()
# XS function. If a constant is not found then control is passed
# to the AUTOLOAD in AutoLoader.
my $constname;
($constname = $AUTOLOAD) =~ s/.*:://;
croak "& not defined" if $constname eq 'constant';
my $val = constant($constname, @_ ? $_[0] : 0);
if ($! != 0) {
if ($! =~ /Invalid/) {
$AutoLoader::AUTOLOAD = $AUTOLOAD;
goto &AutoLoader::AUTOLOAD;
}
else {
croak "Your vendor has not defined PowerBuilder::ORCA macro $constname";
}
}
eval "sub $AUTOLOAD { $val }";
goto &$AUTOLOAD;
}
bootstrap PowerBuilder::ORCA $VERSION;
# Preloaded methods go here.
sub new {
shift;
my ($lib_list,$app_lib,$app_name)=@_;
my $self={};
bless $self;
$self->{SID}=SesOpen() or croak("Can't open ORCA sesion");
my ($rc,$err);
if ($lib_list) {
$rc=$self->SetLibList((@$lib_list));
if ( $rc ) {
$err=$self->GetError();
$self->Close();
croak($err."(ORCA RC=$rc)");
return undef;
}
}
if ($app_lib && $app_name) {
$rc=$self->SetAppl($app_lib,$app_name);
if ( $rc ) {
$err=$self->GetError();
$self->Close();
croak($err."(ORCA RC=$rc)");
return undef;
}
}
return $self;
}
sub LibDirList {
my ($self,$pbl,$type)=@_;
my $res=[];
my @tmp;
my $rc=$self->LibDir($pbl,\@tmp);
croak($self->GetError) if $rc;
if ( defined($type) ) {
for my $e ( @tmp ) {
push @$res,$e->{Name} if $e->{Type}==$type;
}
} else {
for my $e ( @tmp ) {
push @$res,$e->{Name};
}
}
@$res;
}
sub LoadDll {
my $dll=shift;
if ( ! defined($dll) ) {
if ( exists($ENV{ORCA_DLL}) ) {
ORCA_Init($ENV{ORCA_DLL});
$PowerBuilder::ORCA::ORCA_Dll=$ENV{ORCA_DLL};
return;
} else {
my @dlls=qw( pborc90.dll pborc80.dll pborc70.dll pborc60.dll pborc050.dll );
for my $d ( split(/;/,$ENV{PATH}) ) {
for my $dll ( @dlls ) {
if ( -f "$d\\$dll" ) {
ORCA_Init("$d\\$dll");
$PowerBuilder::ORCA::ORCA_Dll="$d\\$dll";
return;
}
}
}
croak("The ORCA dll ".join(",",@dlls)." not found in PATH: ");
}
} else {
if ( -f $dll ) {
ORCA_Init($dll);
$PowerBuilder::ORCA::ORCA_Dll=$dll;
return;
} elsif ( $dll !~ /[\\\/]/ ) {
for my $d ( split(/;/,$ENV{PATH}) ) {
if ( -f "$d\\$dll" ) {
ORCA_Init("$d\\$dll");
$PowerBuilder::ORCA::ORCA_Dll="$d\\$dll";
return;
}
}
croak("The ORCA dll $dll not found in PATH");
} else {
croak("The ORCA dll does not exist: $dll");
}
}
}
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
=head1 NAME
PowerBuilder:: ORCA - Perl interface to PowerBuilder ORCA API
=head1 SYNOPSIS
use PowerBuilder::ORCA qw/:const/;
#open new ORCA session
my $ses=new PowerBuilder::ORCA(['d:\WORK\C\xs\PowerBuilder\ORCA\pbtest.pbl'],
'd:\WORK\C\xs\PowerBuilder\ORCA\pbtest.pbl',
'pbtest');
#now, it is possible to carry out manipulations with objects
my $rc=$ses->Export("pbtest.pbl","f_is_dir",PBORCA_FUNCTION,$buf);
my %h;
$ses->EntryInfo("pbtest.pbl","f_db_connect",PBORCA_FUNCTION,\%h);
#close session
$ses->Close();
=head1 DESCRIPTION
This module enables to use Powersoft Open Library API (ORCA) from Perl. ORCA
is software for accessing the PowerBuilder Library Manager functions that
PowerBuilder uses in the Library painter. A perl script
can use ORCA to do the same kinds of object and library management
that the Library painter interface provides.
ORCA was created for CASE tool vendors as part of the Powersoft CODE
(Client/Server Open Development Environment) program. CASE tools needed
programmatic access to PowerBuilder libraries to create and modify
PowerBuilder objects based on an application design.
To execute programs using ORCA API it is necessary to have pborcNN.dll, which
is part professional and enterprise versions of PB, where NN - number of PB version.
For example, PowerBuilder version 6 - pborc60.dll.
The detailed description of ideology and functions of ORCA can be found in the documentation on PB
( http://sybooks.sybase.com/onlinebooks/group-pb/adt0650e/orca/ ). It is B<recommended> to read
this documentation.
Conformity of ORCA API functions and methods given ORCA.pm:
ORCA API ORCA.pm
------------------------------ ------------------
PBORCA_SessionClose Close
PBORCA_SessionGetError GetError
PBORCA_SessionOpen new
PBORCA_SessionSetCurrentAppl SetAppl
PBORCA_SessionSetLibraryList SetLibList
PBORCA_LibraryCommentModify LibCommentModify
PBORCA_LibraryCreate LibCreate
PBORCA_LibraryDelete LibDel
PBORCA_LibraryDirectory LibInfo,LibDir,LibDirList
PBORCA_LibraryEntryCopy Copy
PBORCA_LibraryEntryDelete Del
PBORCA_LibraryEntryExport Export
PBORCA_LibraryEntryInformation EntryInfo
PBORCA_LibraryEntryMove Move
PBORCA_CheckOutEntry CheckOut
PBORCA_CheckInEntry CheckIn
PBORCA_ListCheckOutEntries ListCheckOutEntries
PBORCA_CompileEntryImport Import
PBORCA_CompileEntryImportList ImportList
PBORCA_CompileEntryRegenerate Regenerate
PBORCA_ExecutableCreate ExeCreate
PBORCA_DynamicLibraryCreate DllCreate
PBORCA_ObjectQueryHierarchy ObjectQueryHierarchy
PBORCA_ObjectQueryReference ObjectQueryReference
=head1 METHODS
=head2 Error handling
The majority of functions return a nonzero error code in a case
unsuccessful completion. The error message can be obtained trought
GetError function.
Error codes:
Code Description
---- -----------------------------------
0 Operation successful
-1 Invalid parameter list
-2 Duplicate operation
-3 Object not found
-4 Bad library name
-5 Library list not set
-6 Library not in library list
-7 Library I/O error
-8 Object exists
-9 Invalid name
-10 Buffer size is too small
-11 Compile error
-12 Link error
-13 Current application not set
-14 Object has no ancestors
-15 Object has no references
-16 Invalid # of PBDs
-17 PBD create error
-18 Source Management error
=head2 Initialization
=over 4
Before the beginning of work it is necessary to specify name of ORCA dll file. Name of dll
depends on PB version.
=item PowerBuilder::ORCA::LoadDll($dll_file);
=item PowerBuilder::ORCA::LoadDll();
Loads specified dll. If file name specified without path - searches for
dll in PATH. If no file specified, function checks environment variable ORCA_DLL.
If it exists, loads specified dll. If the variable not exists, searches in PATH
for dll of version 9,8,7,6 or 5 and loads the first found. If nothing has helped - dies.
The name of loaded dll is kept in a variable $PowerBuilder::ORCA::ORCA_Dll.
=back
=head2 Session management
=over 4
=item $ses=new PowerBuilder::ORCA;
=item $ses=new PowerBuilder::ORCA(\@lib_list);
=item $ses=new PowerBuilder::ORCA(\@lib_list, $app_pbl, $app_name);
Creates new session object, establishes an ORCA session and returns a handle
that you use for subsequent ORCA calls.
The second variant of a call also establishes the list of libraries for an
ORCA session (see SetLibList).
The last variant also establishes the current application object for an ORCA session
(see SetAppl).
=item $rc=$ses->SetLibList($pbl1,$pbl2,...)
You must call SetLibList and SetAppl before calling any ORCA function that compiles
or queries objects. Library names should be fully qualified wherever possible.
You can set the current application and library list only once in a session.
If you need to change either the library list or current application after
it has been set, close the session and open a new session.
ORCA uses the search path to find referenced objects when you regenerate or
query objects during an ORCA session. Just like PowerBuilder, ORCA looks through
the libraries in the order in which they are specified in the library search path
until it finds a referenced object.
You can call the following library management functions and source control functions
without setting the library list:
CommentModify
LibCreate
LibDel
LibInfo, LibDir, LibDirList
Copy
Del
Export
EntryInfo
Move
CheckOut
CheckIn
=item $rc=$ses->SetAppl($pbl,$obj)
You must set the library list before setting the current application.
You must call SetLibList and then SetAppl before calling any ORCA function
that compiles or queries objects. The library name should include the full
path for the file wherever possible.
You can set the library list and current application only once in a session.
If you need to change the current application after it has been set, close
the session and open a new session.
The name of pbl should be specified B<in accuracy> as in SetLibList call.
=item $ses->Close()
Terminates an ORCA session, releases resources.
=item $errmsg=$ses->GetError()
You can call GetError anytime another ORCA function call results in an error.
When an error occurs, functions always return complete error message.
If there is no current error, the function will return an empty string.
=back
=head2 Manipulations with objects
=over 4
=item $rc=$ses->EntryInfo($pbl,$obj,$type,\%hbuf)
Returns the information on object $obj of type $type from library $pbl. The information
Includes the comment, the size of the source text, the size of object and
date and time of last modification. The information returned in hash %hbuf. Keys of hbuf
correspond to the fields of structure PBORCA_ENTRYINFO:
Key PBORCA_ENTRYINFO field
----------- ---------------------------
Comments lpszComments
CreateTime lpszCreateDate, lpszCreateTime
ObjectSize dwObjectSize
SourceSize dwSourceSize
Note: SourceSize ORCA returns incorrectly.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->Export($pbl,$obj,$type,$buf)
Exports the source code for a PowerBuilder library entry to a buffer $buf.
The comparable function in the Library painter saves the exported source in a text file.
The Library painter includes two header lines in the file. ORCA does not add
header lines in its export buffer.
In the buffer, the exported source code includes carriage return (hex 0D)
and newline (hex 0A) characters at the end of each display line.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->Import($pbl,$obj,$type,$comment,$syntax,\$errbuf)
=item $rc=$ses->Import($pbl,$obj,$type,$comment,$syntax,\@errbuf)
Imports the source code for a PowerBuilder object into a library and compiles it.
If there are compilation errors $rc ==-11 and error messages placed to $errbuf.
You must set the library list and current Application object before calling this function.
When errors occur during importing, the object is brought into the library
but may need editing. An object with minor errors can be opened in its
painter for editing. If the errors are severe enough, the object can fail
to open in the painter and you will have to export the object, fix the
source code, and import it again.
=item $rc=$ses->ImportList(\$errbuf,
{
Library=>'lib1.pbl',
Name=>'f_func1',
Type=>PBORCA_FUNCTION,
Comment=>'comment 1',
Syntax=>'source_code_of_f_func1'
},
{
Library=>'lib2.pbl',
Name=>'another_object_name',
Type=>PBORCA_type_of_object,
Comment=>'comment 2',
Syntax=>'source_code_for_object'
} ...
);
=item $rc=$ses->ImportList(\@errbuf,
...
Imports the source code for a list of PowerBuilder objects into libraries
and compiles them.
If there are compilation errors $rc ==-11 and error messages placed to $errbuf.
You must set the library list and current Application object before calling this function.
ImportList is useful for importing several interrelated objects--for example,
a window, its menu, and perhaps a user object that it uses.
=item $rc=$ses->Regenerate($pbl,$obj,$type,\$errbuf)
=item $rc=$ses->Regenerate($pbl,$obj,$type,\@errbuf)
Compiles an object in a PowerBuilder library.
If there are compilation errors $rc ==-11 and error messages placed to $errbuf.
$errbuf can be the reference to a scalar or the reference to an array.
In the first case the scalar contains all error messages incorporated into a line.
In the second case function return errors as array of hashes, each hash has keys:
Level
MessageNumber
MessageText
ColumnNumber
LineNumber
You must set the library list and current Application object before calling this function.
=item $rc=$ses->ApplicationRebuild($type,\$errbuf)
=item $rc=$ses->ApplicationRebuild($type,\@errbuf)
Compiles all the objects in the libraries included on the library list. If
necessary, the compilation is done in multiple passes to resolve circular
dependencies.
You must set the library list and current application before calling this function.
If you use the compile functions, errors can occur because of the order the
objects are compiled. If two objects both refer to each other, then simple
compilation will fail. Use PBORCA_ApplicationRebuild to resolve errors due
to object dependencies. PBORCA_ApplicationRebuild resolves circular
dependencies with multiple passes through the compilation process.
If there are compilation errors $rc ==-11 and error messages placed to $errbuf.
$errbuf can be the reference to a scalar or the reference to an array.
In the first case the scalar contains all error messages incorporated into a line.
In the second case function return errors as array of hashes, each hash has keys:
Level
MessageNumber
MessageText
ColumnNumber
LineNumber
=item $rc=$ses->Copy($src_pbl,$dst_pbl,$obj,$type)
Copies a PowerBuilder library entry from one library to another.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->Move($src_pbl,$dst_pbl,$obj,$type)
Moves a PowerBuilder library entry from one library to another.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->Del($pbl,$obj,$type)
Deletes a PowerBuilder library file from disk.
You don't need to set the library list or current application before calling this function.
=back
=head2 Manipulations with libraries
=over 4
=item $rc=$ses->LibInfo($pbl,$comment,$n_obj)
Returns the information on library $pbl. $comment - the comment, $n_obj - number
Objects in library.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->LibDir($pbl,\@objects);
The array @objects is filled by the information on objects in library $pbl.
Each element of @objects - the reference to a hash with the following keys:
Name a name of object
Type type of object
Size the size of object
CreateTime time of creation of object
Comment the comment
You don't need to set the library list or current application before calling this function.
=item $list_ref=$ses->LibDirList($pbl[,$type])
Returns the reference to a array with names of objects of the given type in library
$pbl. If the type is not given - returns names of all objects. It is possible
to use LibDirList in for loop:
for my $obj_name ( LibDirList('lib1.pbl') ) {
...
}
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->LibCreate($pbl,$comment)
Creates library with a name $pbl.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->LibDel($pbl)
Deletes library with a name $pbl.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->LibCommentModify($pbl,$new_comment);
Sets the comment for library $pbl.
You don't need to set the library list or current application before calling this function.
=back
=head2 VCS interface
=over 4
=item $rc=$ses->CheckOut($obj,$type,$master_pbl,$work_pbl,$user_id,$copy)
Checks out a library entry from a master library (the source) to a work library (the destination).
$copy - an integer whose value indicates whether to simply change the check-out
flags in the libraries or to copy the object to the work library, too. Values are:
0 -- Mark the object as checked out in the master and work libraries,
but leave the copy of the object in the work library as is.
Do not overwrite it with the copy in the master library
1 -- Mark the object as checked out in the master and work libraries and copy
the object from the master library to the work library
$user_id - the version control user ID.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->CheckIn($obj,$type,$master_pbl,$work_pbl,$user_id,$move)
Checks in a library entry from a work library (the destination) to a master
library (the source). $move - an integer whose value indicates whether to
simply change the check-out flags in the libraries or to move the object
from the work library to the master library, deleting it from the work
library. Values are:
0 -- Clear the check-out status of the object in the master and work
libraries, but leave the copy of the object in the master library as is. Do
not overwrite it with the copy in the work library and do not delete it
from the work library
1 -- Clear the check-out status of the object in the master and work
libraries and move the copy in the work library to the master library,
deleting it from the work library
$user_id - the version control user ID. The ID must be the same one used
to check out the object.
You don't need to set the library list or current application before calling this function.
=item $rc=$ses->ListCheckOutEntries($pbl,\@storage);
Returns check-out information for objects in a PowerBuilder library.
Each element of array is a hash with the following keys:
LibName a name of library
Name a name of object
UserID a name of the user
Mode the status (s - source, r - registered, d - distanation)
Hash corresponds to structure PBORCA_CHECKOUT.
You don't need to set the library list or current application before calling this function.
=back
=head2 References and inheritance
=over 4
=item $rc=$ses->ObjectQueryHierarchy($pbl,$obj,$type,\@storage);
Queries a PowerBuilder object to get a list of the objects in its ancestor
hierarchy. Places the result to array @storage. Only windows, menus, and
user objects have an ancestor hierarchy that can be queried.
You must set the library list and current Application object before calling this function.
=item $rc=$ses->ObjectQueryReference($pbl,$obj,$type,\@storage);
Queries a PowerBuilder object to get a list of its references to other
objects. Places the result to array @storage. Each element of @storage is
a hash with following keys:
LibName library name
Name object name
Type object type
RefType reference type (o - open, s - simple)
Hash corresponds to structure PBORCA_REFERENCE.
You must set the library list and current Application object before calling this function.
=back
=head2 Compilation
=over 4
=item $rc=$ses->DllCreate($pbl,$pbr,$options);
Creates a PowerBuilder dynamic library (PBD) or PowerBuilder DLL.
Before calling this function, you must have previously set the library list
and current application.
If you plan to build an executable in which some of the libraries are
dynamic libraries, you must build those dynamic libraries before building
the executable.
$options - a long value that indicates which code generation options to
apply when building the library (combination of constants described in
L<Code generation parameters>.
=item $rc=$ses->SetExeInfo({
CompanyName => 'CompanyName',
ProductName => 'ProductName',
Description => 'Description',
Copyright => 'Copyright',
FileVersion => '9,9,9,9',
FileVersionNum => '8,8,8,8',
ProductVersion => 'ProductVersion',
ProductVersionNum => '7,7,7,7',
};
Sets the version information, used at creation of the .exe.
=item $rc=$ses->ExeCreate($exe,$ico,$pbr,\@pbd_flags,$options,\$errors);
You must set the library list and current Application object before calling this function.
Creates a PowerBuilder executable with Pcode or machine code. For a machine
code executable, you can request several debugging and optimization
options. If you are creating a server for a distributed application, you
can specify that it be an Open Server executable.
The ORCA library list is used to create the application. You can specify
which of the libraries have already been built as PBDs or DLLs and which
will be built into the executable file.
Parameters:
$exe - a name of an executed file (should not exists)
$ico - an icon file
$pbr - a resources (.pbr) file
@pbd_flags - for every pbl in library list:
0 - to include objects in .exe a file;
1 - to use already constructed pbd/dll
The number of elements in a file should correspond to number of
Libraries in library list
$options - parameters of generation of a code (see L<Code generation parameters>)
$errors - the buffer for errors.
=back
=head1 Exported constants
Constans are exported, if tag const specified:
use use PowerBuilder:: ORCA qw/:const/;
=head2 Types of objects
PBORCA_APPLICATION
PBORCA_DATAWINDOW
PBORCA_FUNCTION
PBORCA_MENU
PBORCA_PIPELINE
PBORCA_PROJECT
PBORCA_PROXYOBJECT
PBORCA_QUERY
PBORCA_STRUCTURE
PBORCA_USEROBJECT
PBORCA_WINDOW
=head2 Code generation parameters
PBORCA_P_CODE
PBORCA_MACHINE_CODE
PBORCA_MACHINE_CODE_NATIVE
PBORCA_MACHINE_CODE_16
PBORCA_P_CODE_16
PBORCA_OPEN_SERVER
PBORCA_TRACE_INFO
PBORCA_ERROR_CONTEXT
PBORCA_MACHINE_CODE_OPT
PBORCA_MACHINE_CODE_OPT_SPEED
PBORCA_MACHINE_CODE_OPT_SPACE
PBORCA_MACHINE_CODE_OPT_NONE
=head2 Rebuild type
PBORCA_FULL_REBUILD
PBORCA_INCREMENTAL_REBUILD
PBORCA_MIGRATE
=head1 AUTHOR
Ilya Chelpanov, ilya@macro.ru, chelpanov@mail.ru
http://i72.by.ru/eng/, http://i72.narod.ru/eng/
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
PowerBuilder online books, "ORCA Guide"
http://sybooks.sybase.com/onlinebooks/group-pb/adt0650e/orca/
Demo applications pbexe and reslst on my home page http://i72.by.ru/eng/.
=cut