The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
###############################################################################
#
# HL7 API: README
#
###############################################################################

Contents
--------

1.0 Introduction
2.0 Usage
2.1 Creating messages
2.2 Sending/receiving
2.3 Other modules and this API
3.0 History


1.0 Introduction
----------------

This is the Perl HL7 API. It is a very simple, but rather flexible API
for use in Perl applications (or even in C applications, see for
example http://zwebit.sourceforge.net/). The API is not fixed yet, but
has been used in production environments and has evolved in the
process, into a useful level of abstraction.

The focus of this API is on providing functionality for the
composition, manipulation and decomposition of HL7 messages, not
providing hundreds of prefab HL7 messages. In HL7 terms: this API
focuses on the HL7 syntax, not the semantics. This makes the API
support all versions that use the classic HL7 syntax, that is,
versions untill 3.x. This API does not do XML!

Please refer to the POD documentation for detailed examples and the
full API documentation, or consult the generated manual pages on
http://hl7toolkit.sourceforge.net/. The POD man pages will be auto
generated after installation of the package. Use 'man
Net::HL7::Message' for instance, to get the document on the Message
class.

You might also be interested in the hl7d and hl7qd packages, found on
the same site. The hl7d is a a pluggable, forking HL7 server that can
be used to dispatch HL7 messages to for instance database tables,
files, etc. The hl7qd is a queueing daemon that manages HL7 message
queues. This daemon can accept messages on the filesystem, from a
database, etc.


2.0 Usage
---------

2.1 Creating messages
---------------------

The main focus of the HL7 API is on the Net::HL7::Message class,
assuming this class is the one you will most likely use. You can
create HL7 messages in roughly two ways:

1. creating an empty message with the Net::HL7::Message class, adding
   segements as you go;
2. creating a message based on a string representation of a HL7 
   message.

An basic example of the first way is:

	use Net::HL7::Message;
	use Net::HL7::Segment;
	use Net::HL7::Segments::MSH;

	my $msg = new Net::HL7::Message();

and set some segments and fields like:

	my $msh = new Net::HL7::Segments::MSH();
	my $pid = new Net::HL7::Segment("PID");

	$pid->setField(3, "1231313");
	
	$msg->addSegment($msh);
	$msg->addSegment($pid);

The second method goes like:

	use Net::HL7::Message;

	my $str = "MSH|^~\\&|||MyApp||20040202145837|||20040202145837.66528|P|2.4|||AL|NE\r";
	$str .= "QRD|20040202|fld3|||||fld2|fld1";

	my $msg = new Net::HL7::Message($str);

To check whether this yields the desired message, do:

	print $msg->toString(1);


2.2 Sending/receiving
---------------------

When a message has been created, the obvious thing to do with it would
be to send it off to some HL7 server, and handle the result.  This can
be achieved with the Net::HL7::Connection class. A simple example is
this:

	use Net::HL7::Connection;

	... create a message

	my $conn = new Net::HL7::Connection("hl7server.somedomain.org", 12011);

	$conn || die "Couldn't connect";

	my $resp = $conn->send($msg);

	$resp || die "No response";

	my $msh = $resp->getSegmentByIndex(0);

	... etc

but consult the man page of the Net::HL7::Connection (and even the
Net::HL7::Daemon) for details.


2.3 Other modules and this API
------------------------------

When building some HL7 Perl module, you might want to require a
specific version of this package. You can simply say:

	'PREREQ_PM' => { 'Net::HL7' => 0.66 }

in the Makefile.PL of your Perl thingy that requires this version.

For more detailed usage of every class, please consult the API
documentation on http://hl7toolkit.sourceforge.net/ or generate the
POD's yourself (man perlpod).


3.0 History
-----------

0.76:
* Added getFieldAsString method to Segment
* Added tests for above
* Made getSegmentAsString use getFieldAsString 

version 0.75:

* Fixed regex describing segment name in Message.pm for compatibility
  with all segment names.

version 0.74:
* Fixed documentation issue (again, hinted by Brent B. Powers)
* Added removeSegmentByName method (added by Sebastian John)
* Fix for regex describing segment name in Message.pm, hinted by Brent B.Powers

version 0.73:
* Fixed issue 1035505 with proposed patch of Brent B. Powers
* Fixed issue 1034857
* Fixed issue 1033989 with proposed patch of Brent B. Powers

version 0.72:
* Fixed broken Message.pm: new message from string with subcomponents
  didn't produce a correct string with toString. Thanx to Jason Aragorn 
  Tobias Lunn <jlunn@coderyte.com> of CodeRyte, Inc..
* Added untaint in Message, so that no errors are produced when using
  the tainted mode (like the hl7d does) 
* Added getSegmentAsString and getSegmentFieldAsString methods to Message, 
  after a proposal by H.Emery Ford (emery_ford@bigfoot.com).

version 0.71:
* Fixed broken MANIFEST: added lib/Net/HL7.pm

version 0.70:
* Full redesign of internal structure of the Message and Segment
  classes. Changes have been made to the toString method of the
  Message, and to the constructor when providing a string representation
  of a HL7 message.
* Added the possibility of passing an array of field values to the
  constructor of the Segment.
* Removed automatic creation of a MSH segment when creating an HL7 
  message.
* Added better (sub)composed fields support on Segment getField method.
* Added the Net::HL7 module, to provide a version number of the whole 
  package to Perl 'things' requiring a specific version, and as a container
  for global HL7 properties, like control characters.
* Refactored tests to use Test::More after mysterious failing of
  existing tests under Perl 5.8.2, due to a change in the implementation
  of the 'eq' operator regarding 'undefined' (?).

version 0.68:
* Added more documentation (this is an ongoing effort...)
* made setField on segment accept multiple values. These are joined with
  the component separator.
* Added the HL7 NULL variable for the setField operation on a segment.
* Fixes in MSH segment due to some reference interference quirks on 
  Solaris.
* Added size method to Segment
* Made ACK message type copy full MSH when initialized with message, then
  set it's own specific fields.
* Fixed some complaints when running in strict mode on uninitialized values.
* Fixed some tests that used undefined values.

version 0.67:
* Added COMPONENT_SEPARATOR, REPETITION_SEPARATOR, ESCAPE_CHARACTER and
  SUBCOMPONENT_SEPARATOR to the MSH segment. The setField method on this
  segment, on index 2 now actually changes the values of these variables.
  Also checks on setting field 1 on MSH, whether input is just 1 char.
* Fixes on ACK, to set the error message.  
* Check on segment id: it must be exactely three characters long, upper 
  case.
* Fixed Makefile.PL, so it now really installs into the Perl lib path.
* Added more methods to the Message to manipulate segments.

version 0.66:
* Implemented the getNextRequest method to actually read new data. The
  getRequest method only reads data from the socket if there's no request
  cached.

version 0.65:
* the getRequest method of the Net::HL7::Daemon::Client has been enabled for
  multiple incoming messages. This means that the getRequest method now tries
  to read from the socket every time it is called.
* Fixed some documentation

version 0.64:
* Fixed error in daemon and ack tests
* Fixed erroneous setting of MSH fields in Message.pm
* set MSH(11) to P and MSH(15) to AL per default
* Made new() method of Message also split message string on \n
* ACK now takes MSH(11) and MSH(12) from incoming MSH, and sets MSH(15) and MSH(16)
  to the empty string.
* Fixed erroneous sendAck and sendNack methods. The stuff is now sent as a single 
  line, to prevent perl from inserting separators, like end of lines, etc.

version 0.63:
* fixed some POD errors
* added the sendResponse method to Net::HL7::Daemon::Client
* Removed NACK module: it doesn't exists in the HL7 world.
* The MSH segment now uses index 1 of it's fields for the FIELD_SEPARATOR value;
  other fields have moved one to the right
* added setAckCode method to ACK, to be able to set the error for the acknowledgement.

version 0.62:
* Fixed erroneous read of input buffer for Client
* Added ACK, NACK messages
* Added MSH segment
* getSegmentByName is removed
* Made the Daemon and the Client inherit from IO::Socket, so you can more 
  easy do things with forking and other server operations you would 
  perform on sockets.
* Made several constructors set segments and values, like auto-adding the
  MSH segment to every instance of Message.

version 0.61:
* Moved the stuff to a new namespace (Net::HL7)
* Created a Daemon, resembling the HTTP::Daemon
* Created the Request and Response classes
* added tests

version 0.5:
* Added the getField method to HL7::Message
* repaired broken message parse for HL7::Message constructor

version 0.4:
* Removed spurious newline between segments.