Pages

Minimal ASIO TCP client

Without a client, we can't even check if the ASIO TCP server we have written in the previous post actually works.

This post is ancient (February 2011), please follow the link to its newer version I have written on March 2018. Thank you.

Here are the include files we'll need for our client:
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>

It should be clear why we need Boost ASIO and the standard iostream, boost array is not strictly a necessity, but helps us to keep the code simpler. We'll show how and why at the due time.

We need to provide the client the host name and the port for establish a connection. Host name is going to be passed from the command line by program arguments, the port number is, for this simple test app, just a fixed constant defined in this way:
namespace
{
  const char* HELLO_PORT_STR = "50013";
}
Note that, differently from the server, here we need it defined as a string.

Details on how the host name is extracted from the arguments are irrelevant, assumes it is passed to the current function as a const char* input parameter named host.

All the function body is included in a try-catch block like this:
try
{
  // ...
}
catch(std::exception& e)
{
  std::cerr << e.what() << std::endl;
}
Let's see now the real code:
boost::asio::io_service io_service; // 1

boost::asio::ip::tcp::resolver resolver(io_service); // 2
boost::asio::ip::tcp::resolver::query query(host, HELLO_PORT_STR); // 3
boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end; // 4

boost::asio::ip::tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
while(error && endpoint_iterator != end) // 5
{
  socket.close();
  socket.connect(*endpoint_iterator++, error);
}
if(error) // 6
  throw boost::system::system_error(error);

for(;;) // 7
{
  boost::array<char, 4> buf; // 8
  size_t len = socket.read_some(boost::asio::buffer(buf), error); // 9

  if(error == boost::asio::error::eof) // 10
    break; // Connection closed cleanly by peer
  else if(error)
    throw boost::system::system_error(error);

  std::cout << "[!]"; // 11
  std::cout.write(buf.data(), len); // 12
}
1. As usual with ASIO, we need an I/O service object to do our job.
2. Then we create a resolver, that will provide us a connection to the server.
3. To actually get the connection, we create a resolver::query object for the host-port we are interested in, then we use the resolve() method of our resolver to get an iterator to the resulting connections.
4. As a common idiom states, when we need an "end" iterator to terminate a loop, we generate an iterator of that type calling the default ctor.
5. This loop is not complex, but it is not the most linear piece of code you could see around. The idea is that we want to loop on all the endpoints retrieved by our query on the resolver until we find a working one. So we loop until we find one that is not giving an error when we use it as an endpoint for our socket. The code works smoothly from the second iteration on, the issue is the first one: since there is no previous iteration, we should assume it, initializing error as it was a bad endpoint, and closing the socket in any case, just for homogeneity.
6. If we end the previous loop with an error, no socket connection succeeded, so we throw an error.
7. Another loop, here we have a socket connection to the server, we plan to read from it till we get an EOF.
8. The chosen array size is so ridiculously small to better show how it works.
9. We call read_some() on the socket, to put the retrieved data in our tiny buffer, and iterate the reading until the end. The passed chunck of memory is converted to an asio::buffer object - using a boost::array we spare ourself the bore of passing also the size of the memory block, the asio::buffer is smart enough to get it directly from boost::array.
10. We check the error set by read_some(), EOF actually means that the communication has been correctly completed. If we have a real error, we throw an exception.
11. A bit of fun: we show the actual joins in the data communication.
12. We output the chunk of data currently read from the socket.

Post based on a page from the official boost::asio tutorial. You could get more information in The Boost C++ Libraries online book by Boris Schäling. Chapter seven is about ASIO.

Go to the full post

Minimal ASIO TCP server

Here we are going to write a minimal synchronous TCP "Hello" server that is meant to say hello to the first client that asks for it, and then terminate is execution. It is not very useful, but it should be a good way to get introduced to the Boost ASIO library.

In an ASIO program, we instantiate an io_service object, and than we use it to get the services we require.

This post is ancient (February 2011), please follow the link to its newer version I have written on March 2018. Thank you.


To create an TCP/IP server, we have to specify an endpoint - identified by the used protocol (say, TCP/IP version 4) and a port (I picked up almost randomly 50013 - you should use a port not already used by some other application on you target machine) - and then use the io_service and the endpoint to create an acceptor - an object that we'll use to rule the access on the socket.

Before putting the socket on wait for a client request, we actually have to create the socket itself, using again the io_service as reference.

Here is the code:
#include <iostream>
#include <string>
#include <boost/asio.hpp>

namespace
{
    const int HELLO_PORT = 50013; // 1
}

int main()
{
    try
    {
        boost::asio::io_service io_service;
        boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), HELLO_PORT);
        boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);
        boost::asio::ip::tcp::socket socket(io_service);

        std::cout << "Server ready" << std::endl; // 2
        // just once
        {
            acceptor.accept(socket); // 3

            std::string message("Hello from server\n");
            boost::asio::write(socket, boost::asio::buffer(message)); // 4
            socket.close(); // 5
        }
    }
    catch(std::exception& e) // 6
    {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
}
1. The port used by our Hello Server
2. We have done all the initialization job. A socket has been created on the asio I/O service, and a tcp acceptor keeps together the I/O service and to the specified endpoint.
3. We pass the socket to the acceptor by its accept() method. What happens is that we hang waiting for a client to establish a connection.
4. We have a client-server connection. Now we send a message ot the socket. Since the socket keeps the connection to the client, we expect the client to get this message.
5. Here it's pretty useless to close the socket, since we are about to discard it. But we can easily change the code, making this block an infinite loop, and in this case this call is essential to reuse the socket for the next connection.
6. Any problem, we just signal the issue and terminate.

Post based on a page from the official Boost ASIO tutorial.

Go to the full post

Simple deadline timer

We can use the I/O service object that boost::asio makes available to us to set a timeout both in a synchronous or asynchronous way. Here is a simple example of an asynchronous one.

This post is ancient (February 2011). I would suggest you to follow the link to its updated version (March 2018) instead of reading it.

The program we are about to create sets a three seconds deadline timer on an I/O service object. Then, from the main thread, we create another thread that is going to do some obscure job. When the deadline occurs, we stop the job, and that terminates the program.

This tiny application makes use of a couple of functors. First one, MyJob, encapsulates the job executed by the application in a worker thread till the deadline expires:
class MyJob : public boost::noncopyable // 1
{
private:
    boost::mutex mx_;
    bool outOfTime_; // 2
public:
    MyJob() : outOfTime_(false) {}

    void log(const char* message) // 3
    {
        boost::lock_guard<boost::mutex> lock(mx_);
        std::cout << message << std::endl;
    }

    void timeout() // 4
    {
        outOfTime_ = true;
        log("Timeout!");
    }

    void operator()() // 5
    {
        for(int i = 0; !outOfTime_; ++i)
        {
            std::ostringstream os;
            os << '[' << i << ']';

            log(os.str().c_str());
            boost::this_thread::sleep(boost::posix_time::seconds(1));
        }
    }
};
1. This class can't be copied. No copy ctor or assignment operator is defined for it, not even the default one. Making it deriving from boost::noncopiable is a compact way of saying that.
2. outOfTime_ is a flag, initialized by the ctor to false, that is set to true to stop the infinite loop of this functor.
3. Utility method to do some logging.
4. When the timer expires, it calls this method, to signal that we want to terminate the infinite loop.
5. A loop to output the current delay till we go out of time.

The other functor is required by the timer:
class MyWaitHandler
{
private:
    MyJob& job_; // 1

public:
    MyWaitHandler(MyJob& job) : job_(job) {}

    void operator()(const boost::system::error_code&)
    {
        job_.timeout(); // 2
    }
};
1. Reference to the running job, so we can call it and ask it to stop.
2. When the function is called, we simply signal the timeout occurrence to the job. We don't even check the error status, whatever happens we just terminate.

And here is the main routine for our program:
boost::asio::io_service io; // 1
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3)); // 2

MyJob job; // 3
timer.async_wait(MyWaitHandler(job)); // 4

boost::thread thread(std::ref(job)); // 5
io.run();
job.log("I/O service completed");

thread.join();
job.log("Local thread completed");
1. First thing is creating a I/O service object.
2. We set a deadline timer on our I/O service object.
3. We create the job, that would run in another thread.
4. We say to the deadline timer to wait asynchronously until the expiration of the timer, then call the passed functor - created passing the job by reference.
5. Before running the I/O service, we create a thread on our job - passed by reference (and here we need to use std::ref to force this requirement).

Post based on an example from the official Boost ASIO tutorial. The full C++ source code for this variation is available on github.

Go to the full post

Set of characters

Another useful variation on basic Perl regular expressions is the one represented by the usage of set of characters.

If you can specify your pattern as a bunch of letters where some are fixed and other are varying, we could put the varying ones in a set delimited by square brackets.

Say that we want to check if our string has in it on of these three words: dark, dirk, dork. One way of doing it is considering that they are almost the same. Actually, three letters are exactely the same, and one, the second, is a choice among three different ones.

We can formalize it in this way:

$pattern = "d[aio]rk";
if(/$pattern/) {
print "found!\n";
}

In a set of choices the caret (^) metacharacter (already seen as starting anchor) assumes the sense of a negator.

Our search now is about a pattern starting with "d", ending by "rk", and with just a character in the middle that could be everything "i" or "o". So we won't accept "dirk" or "dork", but we will be cool with "dark" or even "durk":

$pattern = "d[^io]rk";

if(/$pattern/) {
print "found!\n";
}

In a set of character we can specify a range. For instance, if we are looking again for our d.rk word, but now we relax the requisites, letting go anything as second letter that would be a lowecase alphabetical, we could write the check in this way:

$pattern = "d[a-z]rk";
if(/$pattern/) {
print "- found!\n";
}

The second letter now could be anything ranging from a to z (lowercase).

For common choices Perl makes available shortcuts: \d is expanded to [0-9]; \w to [0-9A-Za-z_]; \s to [ \t\n\r]. The uppercase version is a negation. So, for instance, \D means anything but a digit.

Chapter 5 of Beginning Perl by Simon Cozens focuses on regular expressions.

Go to the full post

Anchors

When basic Perl regular expressions are not enough, we improve them using a number of different optional features.

Anchors are useful when we have specific requirements on the position of the pattern in the string. A caret (^) says that we want the pattern being at the beginning of the string, a dollar ($) is for the end.

If we want to check a string for having or not a full stop at its end, we could write this Perl code:

$pattern = "\.";
if(/$pattern$/) {
print "Full stop terminated string\n";
}

Notice that we have to quote the dot (.) because it is a metacharacter, meaning "whatever character but newline".

To check if our string begins with a specific pattern we write something like this:

$pattern = "It";
if(/^$pattern/) {
print "It starts the string\n";
}

Chapter 5 of Beginning Perl by Simon Cozens focuses on regular expressions.

Go to the full post

Simple pattern matching

Perl is strong at text management, and regular expressions are a substantial part of its strenght. Here we start seeing some basic pattern matching.

Given a string:
my $text = "It was a dark and stormy night.";
A common task is checking if a substring is included in it.

The simplest version of it is the exact matching. To check if the substring "dark" is included in the original string, we can write:

if($text =~ /dark/) {
print "Yes, it's dark\n";
}

The matching operator is tilde (~), prefixed with an equal to check for actual matching, with a exclamation mark for the failure of the test, as shown here:

if($text !~ /light/) {
print "No, it's not light\n";
}

As usual in Perl, there is a way of avoiding some typing. If we put the string object of our search in the default scalar:
$_ = $text;
We could rewrite the pattern checking without explicitely refer to the original string. Besides, we could make our checking easier to change using a variable instead of a constant string:

my $pattern = "dark";
if(/$pattern/) {
print "Found it\n";
}

A usual requirement in pattern matching is relaxing it just a bit, to check the pattern in a case insensitive way.

The idea is that we usually want to know to have an OK when we check for "it" and we have "It" (or "IT", and even "iT"). The standard check it is too strict, in this case:

$pattern = "it";
if(not /$pattern/) {
print "Can't find it\n";
}

But we can easily overcome this issue using the "i" modifier:

if(/$pattern/i) {
print "Found it\n";
}

Chapter 5 of Beginning Perl by Simon Cozens focuses on regular expressions.

Go to the full post

Getting out of nested loops

Nested loops make code less readable, so it is usually better avoid them in the first place. On the other side, sometimes they are the most natural solution to a problem, so not using them make the code less clear.

One problem that we could face when we write nested loop is that is not easy to completely get out from it when we are in an internal loop. There are to classical ways to achieve this result: using flag variables, that make the code clumsy; using goto instructions, that make the code a mess.

Perl offer a third way, using a label loop - that actually let us use a sort of domesticated goto mechanism.

The problem that we want to solve is this: we want to loop indefinitely on the input provided by the user, stopping only when one of a list of magic words is provided.

The natural way of implementing a solution is having a loop on STDIN, and then an internal loop for checking the user input against the list of terminators.

The issue is: what should be do when we find that the user input a terminator? We should get out of the external loop, obviously, but how we could achieve it. We have a keyword, last, that is used to step out a loop, but it works only for the current loop.

The solution is marking with a label the external loop (traditionally labels are written all-upperacase) and specifying the loop we want to step out with the last statement:

my @terminator = qw(quit exit stop);

LOOP: while(<>) {
chomp;
for my $check (@terminator) {
last LOOP if $check eq $_;
}
print "---> $_\n";
}
print "Done.\n";

If we used last without specifying the LOOP label, the result would have been disappointing. No way of getting out of the while, we would have been trapped forever (or till an interrupt occurred) in the loop.

Chapter 4 of Beginning Perl by Simon Cozens is about loops and decisions.

Go to the full post

Diamond operator

The Perl so called diamond operator extract a line from the passed file handle. If no file handle is specified, Perl checks the @ARGV array, if at least an element is there, it considers them as file names and tries to open them. If no argument has been passed, the diamond operator assumes standard input (STDIN).

Any time we call the diamond operator, we read a line from the associated file (assumed as a text file). If we are at its end, an undef value is returned. If we are working with a "real" file, a bunch of data stored in the file system, it is quite clear what this means. A bit fuzzier is in case of a stream, like what happens when we use standard input.

To signal that we consider close our stream from standard input to our perl application we use a ctrl-Z (Windows) or ctrl-D (UNIX).

Here is a while loop that run on the standard input till we signal we have got enough of it, and echo the line we entered:

while(defined($_ = <STDIN>)) {
print "---> $_";
}
print "Done\n";

We can rewrite this loop in this way:

while(<>) {
print "---> $_";
}

The latter is more flexible, since it normally works on STDIN, but we can use another file simply passing it as argument to the perl script on the command line.

Chapter 4 of Beginning Perl by Simon Cozens is about loops and decisions.

Go to the full post

Arguments

We can pass arguments from the system command line to Perl. These arguments are made available to us by an array named @ARGV.

If we want to terminate our perl script in case no argument is passed, we could write something like this:
die "You passed no parameter\n" if not @ARGV;
A couple of things to say on this line:

Firstly, I used the so called statement modifier so common in Perl programming. The if check is after the statement that has to be executed in case of success. It looks wierd the first time, but after a while it gets kind of logical.

Secondly, @ARGV is used in a scalar context, so what we are cheching there is its size. The logical "not" operator, equivalent to the exclamation mark "!", negates the value. So, we can read the line in this way: terminate the program printing that message if no argument has been passed.

It is a matter of taste, we could have written equivalently:
die "You passed no parameter\n" unless @ARGV;
Counting on the fact that "unless" is a Perl synonym for "if not".

Once we ensured the array of arguments is not empty, we can print its elements in this way:
print "You passed ".@ARGV." arguments: @ARGV\n";
We uses a first time the @ARGV array in a scalar context, so we get the number of its elements, and then in a interpreted string, so we get all its elements separated by a blank.

If we want to print its elements in a more decorated way, we could use this piece of code:

foreach(@ARGV) {
print "'$_' ";
}
print "\n";

In Perl "for" and "foreach" are synonym. Besides, could be interesting notice the usage of the single quotes inside a double quoted string.

Say that we are expecting numeric values as input arguments, and we want to sum them all and then show the result to the user. We could do that in this way:

my $res;

for (@ARGV) {
$res += $_;
}
print "Sum: $res\n";

But we could use again a statement modifier, this time based on "for":

$res += $_ for @ARGV;
print "Sum: $res\n";

Chapter 4 of Beginning Perl by Simon Cozens is about loops and decisions.

Go to the full post

Switch

Believe it or not, until version 5.8 Perl had no switch. And even now switch is not a core part of the language. How could perl programmers do without it? Emulation is the answer.

We ask a numeric value to the user, there are many possible branches we can take accordingly to the passed value, so the natural way of designing the code would be through a switch. In perl (pre 5.8) we could emulate it in this way:

print "Enter 1 or 2: ";
my $value = <>;
for($value) {
$_ == 1 && do { print "one\n"; last; };
$_ == 2 && do { print "two\n"; last; };
print "unexpected\n";
}

Notice the last statement in the do block. If we didn't write it, the "default" would have been executed by any branch.

From Perl version 5.8 we can use a real switch. For our simple problem this a possible solution:

use Switch;

switch($value) {
case 1 { print "one\n" }
case 2 { print "two\n" }
else { print "unexpected\n" }
}

Go to the full post

Getting input from keyboard

We have written a lot of stuff to the standard output, in the previous Perl examples, now it's time to start getting some input from the standard input.

Nothing easier than that. Here is an improved Hello program that even ask to the user for a name:

print "Input your name: ";
my $name = <STDIN>;
print "Hello, $name!\n";

Actually, this was a buggy example. The fact is that the line we got from standard input includes the newline at its end. We could solve this problem passing the string to the chomp() function, the check for newline at its end and trim them off:

chomp($name);
print "Hello, $name!\n";

But why should we put reading and trimming in two different lines? Won't it be clearer for the reader this?

print "Input your name: ";
chomp(my $name = <STDIN>);
print "Hello, $name!\n";

And if we really want to save some typing, why should we specify STDIN. We normally expect to read data from there so, as usual in Perl, default could be omitted:

print "Input your name: ";
chomp(my $name = <>);
print "Hello, $name!\n";

Go to the full post

Hash

Associative arrays are commonly known as hash in the perl community. If you don't know what I'm talking about in a case nor the other, think to them as unsorted collection of data pairs.

A pair has a first value, known as key (or hash key), that should be unique in the collection; and a second value, that has no special name (it is just called value) and no special constrain either.

We have seen that a perl scalar is identified by a $, an array by @, an hash has a % as a first character in its name.

There is a strong relation between array and hash. So strong, that it is easy create an hash from an array. Given this array:

my @months = ( "Jan", 31, "Feb", 28, "Mar", 31, "Apr", 30, "May", 31, "Jun", 30,
"Jul", 31, "Aug", 31, "Sep", 30, "Oct", 31, "Nov", 30, "Dec", 31
);
print "Months array: @months\n";

We create an hash from it simply by assignment:
my %months = @months;
But we should not expect that an hash would keep the elements in a specific order so, if we assign our hash to another array:

my @monthsA = %months;
print "Months again: @monthsA\n";

We have no guarantee that the elements in monthA would be in the same order that the ones in the month array.

We don't need to create an array as intermediate passage to an hash creation, we could directly initialize it as we would initialize an array:

my %monthsB = (
"Jan", 31,
"Feb", 28,
"Mar", 31,
"Apr", 30,
"May", 31,
"Jun", 30,
"Jul", 31,
"Aug", 31,
"Sep", 30,
"Oct", 31,
"Nov", 30,
"Dec", 31
);

There is an alternative notation, that uses the comma-arrow operator "=>" to make a bit clearer the statement, showing more explicitely the relation between key and value in the hash:

my %monthsC = ( Jan => 31, Feb => 28, Mar => 31, Apr => 30, May => 31, Jun => 30,
Jul => 31, Aug => 31, Sep => 30, Oct => 31, Nov => 30, Dec => 31
);

Since it is so common to have a string as key in an hash, the comma-arrow operator is designed to implicitly quote the characters on its left, converting them in a string.

Once we have an hash, we can get a value associated to a key using a notation close to the one for array:
print "Days in October: $months{Oct}\n";
The difference is that we have to use curly brackets and not square ones.

Instead of using a literal value (without qoutes), we can use a scalar:

my $month= "May";
print "Days in $month: $months{$month}\n";

Let's start again from an empty hash:
my %where;
We can add an element using the the same curly bracket notation we have used for reading an element:

$where{Eva} = "Turin";
print "Eva lives in $where{Eva}\n";

We should pay attention to the fact that key in an hash are unique so, if we use a key that is already in the hash, we don't add a new element, but change the value associated to the existing one:

$where{Eva} = "Berlin";
print "Eva lives in $where{Eva}\n";

Using an hash variable in a scalar context, gives us the number of element currently in the hash (and the total room currently available, more on this in a future post, I guess):
print %where."\n";
Notice that I didn't put the hash variable name in the string, because - try it yourself - that is not a smart move. Perl doesn't recognize it as an hash and print it as a literal string.

To get rid of an element, we use the delete operator:

delete $where{Eva};
print %where."\n";

After using it, we see that the number of element in the hash decreases. If we want to check directly if there is a specified key in an hash, we use the exists() function:

if(!exists $where{Eva}) {
print "No Eva here\n";
}


If we want

There are a couple of useful functions that help us working with hashes. With keys() we get an array containing all the keys in the passed hash, and values() does the same with the values, as someone would have correctly guessed:

my @kMonths = keys(%months);
print "@kMonths\n";

my @vMonths = values(%months);
print "@vMonths\n";

Actually, there are not many cases in which values() comes to help. On the other side, keys() could be very useful - here we see it at work for looping on all the elements of an hash:

for (keys %months) {
print "$_ has $months{$_} days\n";
}

Just do not expect to have the months printed in a specific order.

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

Sort

Another commonly used array function in Perl is sort, that provides a way of ordering an array. By default the ordering algorithm is alphabetical ascending, but we can easily change it.

Say that we have a string array:
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
But we are not happy with its current element disposition. Sometimes we could just need the reverse function, that we can use in this way
for(reverse(@months)) { print "$_\n"; }
But normally we require a more complex rearrangement. If we want to have our months array starting alphabetically with Apr and ending at Sep, we can call sort in its standard way:

my @sorted = sort @months;
print "@sorted\n";

If we want to do something more sophisticated, we can specify an explicit sort routine:

my @revSort = sort { $b cmp $a } @months;
print "@revSort\n";

The sort routine in included in braces and its value is negative, zero or positive accordingly to the relative order of the two parameter, $a and $b, passed to it by sort. In this case we wanted to order the array using an alphabetically descendent order, so we simply reverted the normally used comparison, $a cmp %b.

If you wonder what cmp is, it is a function that behaves just like the old C strcmp() function. I hope you don't need more to be said on the matter.

If we apply the standard sort algorithm to an array of integer, we get the (maybe unexpected) result of ordering it in ascending alphabetical order:

my @numbers = (4, 65, 1, 23, 7);
my @alphaSort = sort @numbers;
print "@alphaSort\n";

Why this happens should be quite clear, when we think better to it. Perl converts automatically numbers to strings, if it finds them in a string context. And by default sort apply the cmp function to decide how to order the elements in the array.

To get the array ordered as we probabily expected it from the beginning, we use the perl operator <=> that behaves like cmp but expecting numbers in input:

my @numSort = sort { $a <=> $b } @numbers;
print "@numSort\n";

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

pop/push and shift/unshift

A Perl array is actually an implementation of the deque (double ended queue) concept. So Perl makes available to us two couples of functions (or operator - Perl looks a bit fuzzy on this distinction) on array: pop/push, to work on its tail; shift/unshift, for its head.

Let's create an array to do some testing:

my @array;
print "Empty array: @array\n";

I often find useful start doing a silly thing. For instance, what happens if I try to pop (that means: remove an item from the tail) an empty array?

my $item = pop @array;
print "Tried to pop but there was nothing in the array!\n" if(!defined $item);

We get no error, simply the result is set to undefined. Notice that I used the (funny) perl inverted syntax for "if", that is quite cool in a case like this.

Remember that for Perl the zero-lenght string, "", is considered equivalent to zero, that's why I had to check the result using the defined operator:

push @array, "";
$item = pop @array;
print "I've popped \"$item\" from the array\n" if(defined $item);

As a bonus, in the previous piece of code we have even seen how to use push to add an element at the end of an array. Actually, since that specific array was empty there was not much to see. Better if we push a couple of items, one after the other:

push @array, "one";
push @array, "two";
print "Array now is: @array\n";
$item = pop @array;
print "I've popped \"$item\" from the array\n";

The couple of functions shift/unshift work just the same, but at the beginning of the array:

unshift @array, "three";
print "Array now is: @array\n";
shift @array;
$item = shift @array;
print "I've shifted \"$item\" from the array\n";

Exactely as pop, also shift returns an undefined value when we try to act on an empty array:

$item = shift @array;
print "Tried to shift but there was no item in the array!\n" if(!defined $item);

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

Dollar-pound

We know that if we use the name of an array variable in scalar context, it is intepreted as its size. But sometimes we are more interested in its last index value. A other-than-perl programmer would probabily just decrease by one the array length, but this is a really not perlish way of seeing it.

Perl provides an explicit operator, dollar-pound ($#), that returns the last item index in the referenced array. I'm ashamed but I should confess I'm not so into perl to see the actual beauty of such a construct.

Given an array, for instance our usual one:
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
This way of looping on it is not considered very perlish:
for(0 .. @months -1) { print "$_: $months[$_]\n"; }
It's true that we have a reason not to use the handy for each loop - we should have used another loop variable to keep track of the current index - but that decrement on the array size is seen as lacking of beauty. It is usually considered nicer using instead the dollar-pound operator:
for(0 .. $#months) { print "$_: $months[$_]\n"; }

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

For each loop

The for each loop is very handy when you want to do something on all the items in an array.

Here we have, again, this array:
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
, we want to print it, but this time we want to show each month name on a different line.

As often happens in Perl, this is a one liner:
for my $month (@months) { print $month, "\n"; }
I declared month as a scalar variable local to the for each loop. Any round in the loop it gets a value from the array months, till the end of it is reached.

Actually, we could rewrite the loop in a even more succint way:
for (@months) { print $_, "\n" }
No loop variable is required, we can safely use the default scalar variable $_ instead, and we can even get rid of the last semicolon in the for each body.

Another example, where there is a change in the array we are working with. The problem here is that we want to double each value in an array:

my @values = ( 10, 20, 30, 40, 50 );
print "initial values: @values\n";
for(@values) { $_ *= 2 }
print "final values: @values\n";

Again a compact solution.

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

Slicing arrays

Perl arrays are so flexible that someone (with that sort of twisted mind) could say it is quite fun to work with them.

Say that you have this definition of an array:
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
And you want to print just some of its elements. Here is a very compact way to say "print the fourth, fifth element, and then all the elements from the eigth to nineth, each of them separated by a blank":
print "@months[3, 4, 7 .. 9]";
The array is in a double quoted string exactely to have it interpolated, that in this case means a blank inserted between each adiacent couple of elements.

Consider another array, and assume this one keep the sale numbers for the past year:
my @sales = (41, 32, 53, 34, 85, 36, 27, 98, 39, 60, 31, 42);
We can easily slice both arrays, months and sales, to show partial results:

print "Summer sales: ";
print "@months[5 .. 7] - @sales[5 .. 7]\n";

And we can use slices to manipulate values in an array. Here, for instance, we swap the values in two months:

print "Swapping Jun and Aug: ";
@sales[5, 7] = @sales[7, 5];
print "@months[5 .. 7] - @sales[5 .. 7]\n";

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

Hello C#

Given my background, C# looks strangely familiar. Sort of a jump in a parallel dimension. It is close to Java, but it is actually not the same. It remembers C++, being definitely something else. And it even has something of old dear Pascal in its Delphi flavour.

Here is how to say hello, writing to the console:

class Hello
{
public static void Main()
{
System.Console.WriteLine("Hello C#");
System.Console.ReadLine();
}
}

Notice the (wierd, from my point of view) uppercase initial for function names.

Using the GUI interface is almost as simple as writing to the console:

using System.Windows.Forms; // 1.

class Hello
{
public static void Main()
{
System.Windows.Forms.MessageBox.Show("Hello C#");
}
}

The only (and minor) issue is that we have to tell the compiler where to get the System.Windows.Forms namespace. System.Console is so standard that we have not to bother about, but this other one has to be specified.

We have to insert in the project an "assembly reference" to the required additional packages. Luckly this is done in a very intuitive mode in the developing environment.

Go to the full post

From MySQL to HTML table

I'm using PHP to generate some HTML. Once estabilished a connection to our MySQL database, I want to perform a select on one of its table and show the result to the user.

Assuming the connection has been successfully estabilished, and that we have its resulting object in $conn, we select all the items from a table getting the resultset in the $result variable:

$query = "select * from events";
($result = mysql_query($query, $conn)) or die("Error accessing database");

The error handling is quite crude: if for any reason the select fails, we just output an error message and terminate the page generation.

Now the fun stuff: we write a function that gets in input the resultset, as returned by a successful call to mysql_query(), and output its data in an HTML table. To make it more readable we alternate yellow rows to light gray ones:

function myPrintAsTable($result)
{
print "<table><tbody>";

$rows = mysql_num_rows($result); // 1.
$cols = mysql_num_fields($result); // 2.
for($i = 0; $i < $rows; ++$i) // 3.
{
$row = mysql_fetch_row($result); // 4.
if($i%2) // 5.
print '<tr style="background-color: lightgrey;">';
else
print '<tr style="background-color: yellow;">';

for($j = 0; $j < $cols; ++$j) // 6.
print "<td>". $row[$j] ."</td>";

print "</tr>";
}
print "</table></tbody>";
}

1. mysql_num_rows() extracts from a resultset the number of rows in it.
2. mysql_num_fields() extracts from a resultset its number of fields (or columns, if we think to them in terms of table terms).
3. Loop on all the rows.
4. mysql_fetch_row() reads the next row and moves the cursor ahead, ready for the next fetch.
5. Set the background color for the current table row in alternate colors.
6. Loop on all the columns and put each field in a different table data tag.

If you have, or could have, multiline text among the data in your table, you should think about using the nl2br() function, that converts any newline in HTML <br> tags, so that you can actually display it to the user.

Go to the full post

MySQL from PHP

Connecting from PHP to MySQL is quite easy, assuming that you have all the required information.

Assuming that we want to connect to a MySQL database on the localhost by the root user that has a very unsafe password to use the test schema, we could do that by this function:

function myConnect() {
$dbHost = "localhost";
$dbUser = "root";
$dbPassword = "password";
$dbSchema = "test";

($conn = mysql_connect($dbHost, $dbUser, $dbPassword)) or die ("Can't connect");
mysql_select_db($dbSchema, $conn) or die ("Can't select database");

return $conn;
}

It's not a nice piece of code, in case of error is quite brutal, actually. But it should be clear what it does.

Go to the full post

Hello PHP

Writing an hello program for PHP is quite straighforward. It just takes a bit to setup the environment, expecially if you are using a Windows machine.

I use Apache as HTTP server, version 2.2, actually. Since the target operating system is Windows, I downloaded the msi installer - that makes the installing job a bit easier.

The only change I made is about the starting/stopping. I changed the Apache2.2 service start mode to manual, and I wrote a couple of tiny script to do the job - but I could have used the cool Apache tool on the tray-bar, instead.

In any case, here is the two one-liner that start and stop the service (they required to be executed by an user having administrator priviledges):

net start Apache2.2

net stop Apache2.2

Then I downloaded PHP for Windows/Apache. Notice that for Apache you need the VC6 version, and not the VC9. I got again the msi, expecting to have less job to do in this way.

Actually, something went wrong, and after installing PHP, Apache did not startup anymore. I had a look at the Apache configuration file, conf\httpd.conf, and I found out that the PHP section was wrong - I had to correct manually the directories in this way:

#BEGIN PHP INSTALLER EDITS - REMOVE ONLY ON UNINSTALL
PHPIniDir "C:/dev/PHP"
LoadModule php5_module "C:/dev/PHP/php5apache2_2.dll"
#END PHP INSTALLER EDITS - REMOVE ONLY ON UNINSTALL

Notice the use of forward slash and not the "windows style" backslash. Obviously the pathname could be different in your setting.

In any case. Done that, I could run my hello php file. I put in the Apache htdocs directory a file named hello.php with inside just this line:
<?php phpinfo(); ?>
The result is a huge HTML page with lot of information on the current PHP configuration.

Go to the full post

asp:Calendar

Besides the standard HTML elements, ASP let us use a bunch of custom controls, like asp:Calendar.

As example, we are going to create an asp:Calendar control that let us select a day, a week, or an entire month.

Here is the snippet from the changed code in the HTML-body-form section:

<asp:Calendar id="myCalendar" runat="server"
OnSelectionChanged="newDateSelection"
SelectionMode="DayWeekMonth" />
<asp:Label id="myDay" runat="server" />
<p><button id="myReset" onserverclick="resetData"
runat="server">Reset</button></p>

We have created an asp:Calendar with the aforementioned selection mode and the specification to call a method called newDateSelection() when the event selectionChange occurs.
We also have an asp:Label myDay that is going to show to the user the current selection.
And finally we have an HTML button, myReset, that we plan to use to clear the selection in the calendar. To get this task done, it calls the method resetData(), that we are about to write.

Here is the associated C# code:

protected void Page_Load(Object s, EventArgs e) // 1.
{
myCalendar.SelectedDate = myCalendar.TodaysDate;
newDateSelection(s, e);
}

void resetData(Object s, EventArgs e) // 2.
{
System.Diagnostics.Debug.WriteLine("resetData()");
myCalendar.SelectedDate = new DateTime();
newDateSelection(s, e);
}

void newDateSelection(Object s, EventArgs e) // 3.
{
myDay.Text = "";

switch(myCalendar.SelectedDates.Count)
{
case 0:
myDay.Text = "No date selected";
break;
case 1:
myDay.Text = myCalendar.SelectedDate.ToShortDateString();
break;
default:
myDay.Text = "From " + myCalendar.SelectedDates[0].ToShortDateString();
myDay.Text += " to " +
myCalendar.SelectedDates[myCalendar.SelectedDates.Count-1].ToShortDateString();
break;
}

myDay.Text += "<br />";
}

1. We want to do some setting up on the calendar control. A good place to do that is when the page is loaded, so we change the Page_Load() method. The setup is actually about selecting the current day in the calendar. Here we change the SelectedDate property for our calendar, setting it to the TodayDate (again a property for the calendar object itself), then we delegate to another method of ours, newDateSelection(), the job of displaying to the user what we have done.
2. This is the method called when we push the reset button. Its first line is there almost just to show how to add some debug message to our code. The second line does the dirty job of creating a new DataTime object with no parameter - the result is what is (usually) considered a fake date, that in this context means no data selected. And finally we call newDateSelection().
3. This method takes care of displaying to the user the date(s) currently selected in the calendar, putting the result in the asp:Label myDay. If we have selected an interval of dates, we show just the first and the last day.

Go to the full post

Using HTML elements

It is quite easy to let ASP use an HTML control. Basically, we put it in the pre-generated form in the ASP page, we give it a runat attribute set to "server", and that it. OK, when used in ASP context the HTML controls require a slight different setting.

For instance the multiple attribute of the select element has to be set to true to show that it is a multiple select, and not to "multiple" as the standard specify. It would be ASP itself to convert it to the HTML code expected on client side.

Here is an example where we create a sort of feedback page for a blog that is about computer programming. We create an HTML input text, myName, where the reader could enter his name; then a multiple select, myLanguages, for the programming languages used; another input text, myOther, for entering more programming languages; another select (but this one is not a multiple one), myInterest, to let the reader give a feedback; a button, myButton, to ask ASP to run the associated C# code; and finally a label, myLabel, where putting the result.

Here is the resulting ASP page:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
void click(Object s, EventArgs e)
{
myLabel.Text = "Feedback from "
+ (myName.Value.Count() != 0 ? myName.Value : "anonymous") + "<br />"
+ "preferred languages: ";

bool anyLanguage = false;
for (int i = 0; i < myLanguages.Items.Count; ++i)
{
if (myLanguages.Items[i].Selected)
{
anyLanguage = true;
myLabel.Text += myLanguages.Items[i].Text + " ";
}
}
if (anyLanguage == false)
myLabel.Text += "not specified";
myLabel.Text += "<br />";

if(myOther.Value.Count() != 0)
myLabel.Text += "Other: " + myOther.Value + "<br />";

myLabel.Text += "Has been the blog useful? " + myInterest.Value;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Feedback</title>
</head>
<body>
<form id="myForm" runat="server">
<div>
<h2>Feedback</h2>
<p>Name:<br /><input type="text" id="myName" runat="server" /></p>
<p>Which programming languages do you currently use?<br />
<select id="myLanguages" runat="server" multiple="true">
<option>C</option>
<option>C++</option>
<option>C#</option>
<option>Java</option>
<option>Perl</option>
<option>SQL</option>
<option>Other</option>
</select>
</p>
<p>If other, please specify:<br />
<input type="text" id="myOther" runat="server" /></p>
<p>Have you found anything interesting in here?<br />
<select id="myInterest" runat="server">
<option>Yes</option>
<option>No</option>
</select>
</p>
<p><button id="myButton" onserverclick="click" runat="server">Confirm</button></p>
<p><asp:Label id="myLabel" runat="server" /></p>
</div>
</form>
</body>
</html>

Relatively speaking, we have written quite a lot of C# code in this example.

Go to the full post

Push my button

Let's see how to use a button in an ASP page.

We'll have a text box (aka input line) where entering a string; and a button to push when done with it. A function would be then called, that would read the string we input and write it in a label.

Being such a simple code, we will put all directly in the ASP page.

I'm using an asp:TextBox named myTextBox; an asp:Button, myButton, with the associated text "OK" and the OnClick even handler associated to a method named click; and finally an asp:Label named myLabel.

The click() method would simply say that the text in myTextBox should be assigned to the text of myMessage.

Here is the resulting ASP page:

<%@ Page Language="C#"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
void click(Object s, EventArgs e)
{
myMessage.Text = myTextBox.Text;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Push me</title>
</head>
<body>
<form id="myForm" runat="server">
<div>
<asp:TextBox id="myTextBox" runat="server" />
<asp:Button id="myButton" text="OK" runat="server" onClick="click" />
<hr />
Your input message is: <asp:Label id="myMessage" runat="server" />
</div>
</form>
</body>
</html>

Go to the full post

Simpler Hello ASP

Actually, for such a simple ASP page like the one we developed in the previous post, using a separate C# file is a bit of an overkill.

We could have instead add to the ASP page just the C# script fragment we need. If we ask to the wizard not to add a separate file for the C# code, we get a slimmer page, that we could easily modify to add our code in a specific script tag.

Here is an ASP page doing exactely the same job of the previous example:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
myTime.Text = DateTime.Now.ToString();
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Hello Even Simpler</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Hello from Even Simpler. Current time is <asp:Label id="myTime" runat="server"/>
</div>
</form>
</body>
</html>

Go to the full post

Hello ASP

Here is a simple ASP page developed with Visual Web Deveoper.using C# as programming language.

I won't spend time on the (long and boring) time required to install on my machine the developing environment, because I don't not know what to say more than it was a long and boring process.

In any case. I have created a new project for an empty Web ASP-NET application. Then in the application I created a new Web Form, and I kept the proposed name (even if I don't expecially like it), Default.aspx. In the process, another file happened to be created, Default.aspx.cs, that looks quite clearly it is a C# file strongly connected with the ASP page.

Here is the source file for the ASP page, slightly change to provide a HTML page title, and some text in the body:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Hello Simple</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Hello from Simple. Current time is <asp:Label id="myTime" runat="server"/>
</div>
</form>
</body>
</html>

In the first line you see a Page directive where it is specified, among other stuff, that we are using C# as undelying language and the name of the file where to look for the C# code.

In the body we can see that a put an asp:Label, that is nothing more than a label, but it has a funny property runat set to server, obviously meaning that is something that has to run on the server. We keep note also of the other property, ID, that looks like a way of providing access to this element.

Actually, if we have a look to the C-Sharp code, we understand more of the asp:Label, since I put there a line referring to it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(Object sender, EventArgs e)
{
myTime.Text = DateTime.Now.ToString();
}
}

All this code was automatically generated but the body of the Page_Load() method. Even not knowing a thing of C# and ASP.NET, it looks that here we are dealing with a class containing code related with a web page, that is picked up as default and that its proposed method is called when the page is loaded, passing an "Object" representing the sender and an "EventArgs" that should be the associated event that caused the method to be called.

What we are doing here is simply setting the Text property of the myTime label, defined in the ASP page, using the current system time converted to a string.

When I executed the project I saw an HTML page having this code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
Hello Simple
</title></head>
<body>
<form method="post" action="Default.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJ(...)Grg==" />
</div>

<div>
Hello from Simple. Current time is <span id="myTime">13/02/11 22:59:16</span>

</div>
</form>
</body>
</html>

Bad formatting, some funny stuff, but, besides this, the most interesting line is in the body, where our asp:Label has been converted in good HTML code.

Go to the full post

Basic stuff on arrays

Perl array is not so low level as its C counterpart, it would make more sense to compare it with C++ std::vector, but it is not defined in a library, instead it is a part of the language itself.

We see at once if a perl variable is an array or a scalar, since the name of an array starts with an at sign (@), while we know that a perl scalar variable name is introduced by a dollar sign ($).

We can initialize a string array a notation that remembers the C one, but it uses round brackets to delimit the elements:
my @names = ("Tim", "Bill", "Jim");
Or we can use a more perl-ish one, that gets rid of quotations and commas:
my @names = qw(Tim Bill Jim);
The result is the same: we have defined an array containing three strings.

When we want to print an array, we usually print it using the interpolated notation:
print "@names\n";
Because the interpolation in case of arrays means inserting a blank between each element - making the result readable.

One may wonder what means assigning an array to a scalar variable:
my $len = @names;
As the chosen variable names should suggest, an array variable in a scalar context is actually evaluated to the length of the array itself. So this perl instruction:
print "$len: @names\n";
should result in an output like this:
3: Tim Bill Jim
We didn't actually need an explicit scalar variable to achieve that result, we could just tell to perl to use the array as a scalar, using the "scalar" operator:
print scalar @names, ": @names\n";

Chapter 3 of Beginning Perl by Simon Cozens is about arrays and associative arrays (hashes).

Go to the full post

Strict global and local variables

If you use the strict directive in your Perl code, and you should do that, you have to specify if a variable you are declaring is local (it is "my" variable) of global (it is "our" variable).

Local variables can't be referenced outside the current scope, and they are the preferred ones, if you want to keep your code reasonable readable.

#!/usr/bin/perl
use strict;
use warnings;

our $gRec = 99; # 1.
my $rec = 4; # 2.
print "Records ", $gRec, ' ', $rec, "\n";
{
my $rec = 88; # 3.
$gRec = 42;
print "Records ", $gRec, ' ', $rec, "\n";
}
print "Record ", $rec, "\n";

1. $gRec is a global variable.
2. $rec is a variable with local file scope.
3. we declare another $rec variable, limited to the current scope, that here hides the local file $rec defined in (2).

Beginning Perl by Simon Cozens is a good book to start with Perl. Scoping is discussed on chapter 2.

Go to the full post

From simple string to here-document

String management in Perl could be surprising for the random user. But after a while you get used of this sometimes cryptical way of defining strings.

The "normal" string usage looks quite a common sight, for the C/C++/Java programmer:
print("Hello!\n");
Here I just printed a line, I hope you already know that backslash-n is the way a newline is represented.

A first surprise comes when we rewrite the print function without using round brackets - they are not mandatory in Perl:
print "Hello!\n";
But now look here:
print 'Hello!\n', "\n";
We are passing to strings to the print function - the single quote in Perl is another delimiter for strings, and not for a single character - and we have both of them printed on standard output.

The single quote string delimiter, acts in a way to let the string interpreted literally: \n is seen just like a couple of normal characters.

If I want to put a single backslash in a double quoted string, I escape it using another backslash:
print "backslash here \\, and at the end:\\", "\n";
Theoretically speaking, using the single quote should avoid the double-backslash trick - but we have to pay attention that our backslash won't be interpreted erroneously as an escape character:
print 'backslash here \, and at the end:\\', "\n";
We had to put a double backslash at the end of the first string, otherwise the \' couple was about to be interpreted as a single quote escaped - breaking the code, since Perl wouldn't find the string terminator.

For more complicated strings the quote-like operators are a good alternative. We delimit the string using a single or double q (instead of a single or double quote) and a slash (or other character like a pipe '|', hash '#', brackets) to start it and a slash (or pipe, hash, ...) to terminate it. Like this:
print qq/'backslash here \, and at the end:\\'/;
When you should generate a real complex string, it could be useful using the here-document (also friendly known as heredoc) concept, to keep things simple.

The idea is that we start the string with a special tag: two less-than and a sequence of characters of our choice (traditionally EOF). We repeat our "magic" sequence at the end of the string. If we want to avoid escaping, we put our sequence in single quotes, like this:

print <<'EOF';
here-document.\' \
here-document.\\\\
I could write anything I want.
EOF

I'm refreshing my Perl knowledge reading Beginning Perl by Simon Cozens. On chapter 2 you could find more information on strings and printing.

Go to the full post

Trigger

A trigger is a sort of procedure that is executed as result of an event generated in the database.

As an example, let's see a trigger that generates a user exception we try to change data in the jobs table in a week day other than wednesday:

create or replace trigger tr_jobs
before insert or update or delete
on jobs
begin
if to_char(sysdate, 'DY') != 'WED' then
raise_application_error (-20900, 'Today no change allowed');
end if;
end;

When this trigger is in the database, if we try to insert a new row:
insert into jobs values('XXX', 'Unknown', 0 , 0);
Update:
update jobs set max_salary = 0;
Or delete:
delete jobs where job_id = 'AD_VP';
We always get a SQL error back - if we don't run these statements on Wednesday.

Chapter 19 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is all about triggers.

Go to the full post

Package

The PL/SQL package helps us to organize our code in a similar way to the header file for C/C++ code.

We create a package, containing the function declarations and, when required, subtype definitions. Then we create the package body, where the functions are defined.

Let's create a package for a couple of utility functions for the employees table, as usual located in the hr oracle test schema:

create or replace package pkg_employee as

subtype fullname_t is varchar2(200);

function fullname(
in_first employees.first_name%type,
in_last employees.last_name%type
) return fullname_t;

function fullname(
in_id in employees.employee_id%type
) return fullname_t;

end;

We have a function, fullname(), with two overloads. One expects first name and last name - and just combine them together, the other requires an employee id as input parameter. Both of them return an object of the subtype, fullname_t, created in the same package.

Now we provide the implementation for the functions:

create or replace package body pkg_employee
as

function fullname(
in_first employees.first_name%type,
in_last employees.last_name%type
) return fullname_t
is
begin
return in_first || ' ' || in_last;
end;

function fullname(
in_id in employees.employee_id%type
) return fullname_t
is
retval fullname_t;
begin
select fullname(first_name, last_name)
into retval
from employees
where employee_id = in_id;

return retval;
exception
when no_data_found then
return 'Not found!';
when others then
return null;
end;

end pkg_employee;

In this case I added the pkg_employee specification to the finale end tag. It is not mandatory, but when things get complex it helps to let the code be clearer.

Now I can use the package in my code, in this way:

declare
l_name pkg_employee.fullname_t;
l_id employees.employee_id%TYPE := 100;
begin
l_name := pkg_employee.fullname(l_id);
dbms_output.put_line(l_name);
end;

Packages are thoroughly discussed in chapter 18 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Function

A PL/SQL function is, basically, a procedure that explicitely returns a value.

Or, other way round, a procedure is a function that explicitely does not return anything.

In any case both procedure and function could return as many values as required in their parameter list, marking any parameter required to be a return value with the "OUT" tag. But only the explicit return value from function could be assigned directly to a value in the caller code as a result of invoking that indipendent code block.

Here is how to create a simple function accepting an input varchar2 parameter and returning another varchar2:

create or replace function country_name(in_id in varchar2)
return varchar2
is
l_country_name countries.country_name%type;
begin
select country_name
into l_country_name
from countries
where country_id = in_id;

return l_country_name;

exception
when no_data_found then
return 'No such country id';
when others then
return 'Unexpected error: ' || sqlerrm;
end;

In case of exception, we trap it and return just an error message to the caller.

Here is how we call the function we just created:

declare
l_country_name countries.country_name%type;
begin
l_country_name := country_name('UK');
dbms_output.put_line(l_country_name);
end;

And that's how to get rid of it:
drop function country_name;

Procedures, functions, and parameters are thoroughly discussed in chapter 17 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Procedure

If you know how to deal with a PL/SQL anonymous block, you should easily grasp the same look and feel in the procedure definition.

The PL/SQL is a block of code that we could call from another PL/SQL block by its name. Besides, we could pass any (reasonable) number of parameters to it.

Here is how we create a procedure for the current schema:

create or replace procedure say_hello(in_name in varchar2)
is
begin
dbms_output.put_line('hello ' || in_name || '!');
end;

We "create or replace" it. So, if we are posting a change in the procedure code we won't get an error. If we prefer to avoid the risk of destroying already existing code, we can just "create" it.

This procedure is named say_hello, this is the name we should use to call it.

It accepts one single input ("in") parameter, a varchar2 named in_name.

The procedure body should not require any further explanation.

Once we have a procedure in our schema, or in an accessible one, we can call it like this:

begin
say_hello('Tom');
end;

We can get rid of our procedure, if we don't need it anymore, dropping it:
drop procedure say_hello;
Assuming our user has the rights to do that, naturally.

Procedures, functions, and parameters are thoroughly discussed in chapter 17 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Passing parameters to cursor

A PL/SQL cursor could be thought like a sort of function that perform a query to the database and makes available the resulting recordset.

Being like a function, there should be a way of passing parameters to it.

Let's change the code we wrote in the previous post. There we have a loop on an explicit cursor that selected all the rows in the countries table.

Here we do something a bit smarter. We want to select just the countries in a specific region. And we want to be able to pass the region id to the cursor from the calling code.

Here is how we can do that:

declare
cursor lc_countries(p_region number) is -- 1.
select * from countries where region_id = p_region; -- 2.
lr_country countries%rowtype;
begin
open lc_countries(4); -- 3.

loop
fetch lc_countries into lr_country;

if lc_countries%notfound then
dbms_output.put_line('---');
exit;
end if;

dbms_output.put_line(lr_country.country_name);
end loop;

close lc_countries;
exception
when others then
dbms_output.put_line('Something went wrong ' || sqlerrm);
if lc_countries%isopen then -- 4.
close lc_countries;
end if;
end;

1. p_region is a parameter to the cursor.
2. We use the parameter passed to the cursor in the SQL statement.
3. With the open call to the cursor, we pass the requested parameter.
4. Another little change in the code about robustness: we ensure the cursor is open before closing it.

We can also specify a default value for the cursor parameter. If we rewrite the line (1) in this way:
  cursor lc_countries(p_region number := 1) is
We can accordingly rewrite line (3) to use the default value for the cursor instead of providing an explicit one:
open lc_countries();
Where the round brackets could be omitted.

More information on data retrieval in PL/SQL in chapter 15 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Loop on an explicit cursor

To loop on an explicit cursor we take advantage of the fact that when we try to read the first element next to the end of a cursor we do not get an exception back, but we simply have the cursor property NOTFOUND set to true.

Here is an example:

declare
cursor lc_countries is select * from countries;
lr_country countries%rowtype;
begin
open lc_countries;

loop
fetch lc_countries into lr_country;

if lc_countries%notfound then -- 1.
dbms_output.put_line('End of cursor');
exit;
end if;

dbms_output.put_line(lr_country.country_name);
end loop;

close lc_countries;
exception
when others then -- 2.
dbms_output.put_line('Something went wrong ' || sqlerrm);
close lc_countries;
end;

1. if the fetch reports that no row is available, setting the cursor property NOTFOUND to true, we end the loop.
2. it's a good idea to consider that we could have some unexpected exception after we open the cursor and before we could close it in the normal execution flow. Checking for exceptions we ensure we properly close it.

More information on data retrieval in PL/SQL in chapter 15 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Implicit cursor

The simple cursor showed in the previous post is an explicit one: we declare it with its associated SQL statement in the DECLARE section of our PL/SQL block, then we explicitely OPEN, FETCH and CLOSE it.

When we write an implicit cursor, we rely on the PL/SQL compiler to do all the under the curtain job and we just get the result in a local variable.

In this example we use an implicit cursor to fetch a row in a local record:

declare
lr_country countries%rowtype; -- 1.
begin
select *
into lr_country -- 2.
from countries
where country_id = 'BE';

dbms_output.put_line(lr_country.country_name || ' ' || lr_country.region_id);
exception
when no_data_found then -- 3.
dbms_output.put_line('no data found');
when too_many_rows then -- 4.
dbms_output.put_line('more than a row found');
end;

1. Declare the record to be used by the implicit cursor.
2. The SQL statement is used by the PL/SQL compiler to generate an implicit cursor that would fetch its first row in our local record variable.
3. If there is not such a row in the table, a exception is raised.
4. Changing the WHERE clause in the SELECT statement to a "like 'B%'" we are going to get more than one row, and so a exception will be raised.

More information on data retrieval in PL/SQL in chapter 15 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Simple cursor

A simple PL/SQL cursor could be thought as a pointer to the result of a query.

The cursor declaration specifies how the query should be run. The we have to OPEN it, to actually perform the query; FETCH a single record from the cursor, to be able working on the data, and finally CLOSE it.

Once the cursor is open, we can check its status showed by a few attributes - in case of implicit cursor we check the attributes of SQL. Trying to read the status of a cursor not already initialized leads to a INVALID_CURSOR exception.

Here is a simple usage example on the countries table from the test HR Oracle schema:

declare
cursor lc_countries is select * from countries; -- 1.
lr_country countries%rowtype; -- 2.
begin
open lc_countries; -- 3.
dbms_output.put_line('Row fetched from cursor: '
|| lc_countries%rowcount); -- 4.

fetch lc_countries into lr_country; -- 5.

if lc_countries%found then -- 6.
dbms_output.put_line('Row fetched');
end if;

dbms_output.put_line('The first fetched country is ' || lr_country.country_name);

close lc_countries;
exception
when invalid_cursor then -- 7.
dbms_output.put_line('Cursor has not been opened yet');
end;

1. Cursor declaration.
2. Record used by the cursor.
3. First step to do is opening the cursor.
4. Attribute rowcount: it returns the number of rows already fetched from the cursor. In this case zero.
5. Then we fetch the cursor, to access a row by the record.
6. Attribute found: true if the fetch operation has been accomplished correctly.
7. The exception we could get when we try to access a cursor attribute.

More information on data retrieval in PL/SQL in chapter 15 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Records in INSERT and UPDATE

We can semplify our PL/SQL code using records to perform INSERT and UPDATE statements.

Here is an example where we try to INSERT a new row in table country, as available in the test Oracle HR schema. If the country id is already in the table, we get an exception, so we fall back to call an UPDATE:

declare
l_country countries%rowtype; -- 1.
begin
l_country.country_id := 'VA'; -- 2.
l_country.country_name := 'Vatican';
l_country.region_id := 1;

insert into countries values l_country; -- 3.
exception
when dup_val_on_index then -- 4.
dbms_output.put_line('Country already inserted');
update countries
set row = l_country -- 5.
where country_id = l_country.country_id;
end;

1. Declaration of a record matching the countries table definition.
2. Record setup
3. INSERT for record: after VALUES no round brackets.
4. Exception when we try to insert a country id already existing.
5. In UPDATE we use the SET ROW clause.

More information on DML in PL/SQL in chapter 14 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Binding by RETURNING

We could bind PL/SQL variables to a SQL DML statement so that it could return values extracted from the database to the PL/SQL block. To do that we use add a RETURNING clause to the SQL statement.

As an example, here is a loop that performs an UPDATE statement on each row of the EMPLOYEES table (again from the Oracle test HR schema). Two local variables are set in the RETURNING clause and then used in the proceeding of the PL/SQL code:

declare
l_salary employees.salary%type;
l_name employees.last_name%type;
begin
for rec in (select * from employees)
loop
update employees
set salary = salary * 1.05
where rec.employee_id = employee_id
returning salary, last_name into l_salary, l_name;

dbms_output.put_line(l_name || ' new salary is ' || l_salary);
end loop;
end;

More information on DML in PL/SQL in chapter 14 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

SQL%FOUND and SQL%ROWCOUNT

We could get information on the most recent execution of a SQL statement in PL/SQL checking a few implicit cursor attributed made available to us.

Here we see a couple of them, SQL%FOUND and SQL%ROWCOUNT, in action.

In a PL/SQL block we run this UPDATE statement:

update family
set surname = 'Smith Dumblee'
where surname like 'S%';

After that, we could check if we modified anything in the database:

if(sql%found) then
dbms_output.put_line('at least one row affected');
else
dbms_output.put_line('no rows affected');
end if;

If we need more precise information, we could use SQL%ROWCOUNT:

case sql%rowcount
when 0 then
dbms_output.put_line('no rows affected');
when 1 then
dbms_output.put_line('one row affected');
else
dbms_output.put_line('more than one row affected');
end case;

More information on DML in PL/SQL in chapter 14 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Collection.exists()

The PL/SQL method collection.exists() could be called on associative array, nested table, varray to check if an element is in the current collection.

It does not throw any exception. Even if the undelying collection has not been initialized, it just returns FALSE.

If parents_t is a varray type available to the current PL/SQL, we could write this code:

declare
parents parents_t := parents_t();
begin
if parents.exists(42) = false then
dbms_output.put_line('This item is not in the collection');
end if;
end;

That prints the message, since that element is not in the collection. More interestingly, even though we don't initialize the varray but just declar it:
parents parents_t;
the result won't change.

Chapter 12 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is all about collections.

Go to the full post

Collection.delete()

We use the delete() method on a PL/SQL collection (associative array, nested table, varray) to delete a single element in it, a subinterval of it, or all its members.

On varray we can call delete() only without argument, to remove all the items in it. The trim() function could be used to remove a single item at the end of the collection.

If we apply delete() on an unitialized nested table or varray, we get a COLLECTION_IS_NULL exception.

As an example, we could modify the code we wrote for testing the associative array inserting a remove call before dumping the data to the output buffer.

If we want to remove all the items, we could write:
l_countries.delete();
We achieve exactely the same result specifying explicitely the range starting from the first element and ending to the last one:
l_countries.delete(l_countries.first(), l_countries.last());
If we want to delete all the items but the extreme ones we could call delete() in this way:

l_countries.delete(
l_countries.next(l_countries.first()),
l_countries.prior(l_countries.last()));

We have remove all items in the interval starting from the next to te first element and ending to the previous to the last one.

We can explicitely provide the key of the element we want to remove, when we know it. For instance, since Brazil was inserted with key 98, here is how we can remove it:
l_countries.delete(98);
Chapter 12 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is all about collections.

Go to the full post

Collection.count()

We could check the number of elements in a PL/SQL collection (associative array, nested table, varray) using the count() function.

In case of a collection that requires initialization (nested table and varray), if its count() method is called before it is initialized, a COLLECTION_IS_NULL exception is raised.

Here is an example that uses the example data we created in the previous post on varray.

declare
l_parents parents_t;
begin
-- dbms_output.put_line('This raise an exception ' || l_parents.count()); -- 1.

select parents
into l_parents
from family
where surname = 'Smith'; -- 2.

dbms_output.put_line('Smiths: ' || l_parents.count());
exception
when collection_is_null then
dbms_output.put_line('Collection is null');
when no_data_found then
dbms_output.put_line('No data found');
when others then -- 3.
dbms_output.put_line('Unexpected: ' || sqlerrm);
end;

1. At this point l_parents has not been initialized, if you uncomment this line you would get a COLLECTION_IS_NULL exception.
2. If no family with surname Smith is in the table, we have a NO_DATA_FOUND exception
3. No other exceptions are expected in this piece of code.

Chapter 12 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is all about collections.

Go to the full post

Varray

In a Oracle database, we can use define datatypes based on VARRAY, a sort of resizable vector with a fixed max size.

Let's say that we have to manage a kindergarten waiting list. We want to put in a table the kid names and the relative parents names. And we want also to be able to manage the case of parents who don't have currently any kid, but still they want to enter in the list (it's a fancy kindergarten with a very long waiting list).

Any kid could have 0, 1, or 2 parents. And this is how we create the type that describes their names:
create type parents_t is varray(2) of varchar2(100);
We could have 0 or 1 kid (twins are not supported):
create type child_t is varray(1) of varchar2 (100);
And now we use these new types for our family table:

create table family (
surname varchar2(100),
parents parents_t,
kid child_t
);

Here is the PL/SQL code to put in the list Ann and Bill Smith, proud parents of Charlie Smith:

declare
parents parents_t := parents_t();
kid child_t := child_t();
begin
parents.extend(2);
parents(1) := 'Ann';
parents(2) := 'Bill';

kid.extend();
kid(1) := 'Charlie';

insert into family (surname, parents, kid)
values('Smith', parents, kid);
end;

And here is the case of Dan Schmidt, single, no kids, but with lot of hopes in the future:

declare
parents parents_t := parents_t();
kid child_t := child_t();
begin
parents.extend(1);
parents(1) := 'Dan';

insert into family (surname, parents, kid)
values('Schmidt', parents, kid);
end;

Chapter 12 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is all about collections.

Go to the full post

Nested table

When programming in PL/SQL we could use SQL nested tables, that behave like (STL C++) vectors of the underlying data.

Being nested tables SQL type, we could store them in a database schema and use them in any PL/SQL block having SELECT access to that type.

Nested tables could be seen as set, an we can apply on them set operators like MULTISET EXCEPT.

As an example, let's create a nested table type of VARCHAR2, declare a few variables ot this type and use them:

declare
type nt_names_t is table of varchar2(20); // 1.
family nt_names_t := nt_names_t(); // 2.
children nt_names_t := nt_names_t();
parents nt_names_t := nt_names_t();
begin
family.extend(4); // 3.
family(1) := 'Mother'; // 4.
family(2) := 'Father';
family(3) := 'Son';
family(4) := 'Daughter';

children.extend(); // 5.
children(1) := 'Son';
children.extend();
children(2) := 'Daughter';

parents := family multiset except children; // 6.

dbms_output.put_line('Parents:');
for l_row in parents.first() .. parents.last() // 7.
loop
dbms_output.put_line(parents(l_row));
end loop;

dbms_output.put_line('Childrens:');
for l_row in children.first() .. children.last()
loop
dbms_output.put_line(children(l_row));
end loop;

dbms_output.put_line('Family:');
for l_row in family.first() .. family.last()
loop
dbms_output.put_line(family(l_row));
end loop;
end;

1. We define locally a nested table type. To create a nested table type in the current schema we would have written:
create or replace type nt_names_t is table of varchar2(20);
2. Before usage, a nested type variable has to be initialized calling the constructor (C++ style).
3. We have to reserve explicitely memory for new elements.
4. In this way we add a new element to the nested table.
5. By default extend() reserves room for one more element.
6. With MULTISET EXCEPT we get a set that is the difference from the left hand to the right hand passed nested tables.
7. An interesting property of nested tables is that we can loop on them using a for loop delimited by its first() and last() element.

Chapter 12 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is all about collections.

Go to the full post

Associative array

PL/SQL makes available associative arrays that we can use to store key-data pairs.

Here is an example where we create an associative array based on the pair { pls_integer, varchar2(20) } where the integer acts as a key:

declare
type aa_names_t is table of varchar2(20) index by pls_integer; -- 1.
l_countries aa_names_t; -- 2.
l_key pls_integer; -- 3.
begin
l_countries(714) := 'Belgium'; -- 4.
l_countries(2) := 'Belize';
l_countries(98) := 'Brazil';
l_countries(12) := 'Burkina Faso';

l_key := l_countries.first(); -- 5.
while(l_key is not null) -- 6.
loop
dbms_output.put_line(l_countries(l_key));
l_key := l_countries.next(l_key); -- 7.
end loop;
end;

1. Instead of an explicit varchar, we could have used as type the one of an existing table row, like this: countries.country_name%type
2. Declaration of a local variable of the just created type.
3. Variable used to loop on the associative array's keys.
4. In this way we insert a new element in the associative array.
5. Get the key of the first row.
6. Loop until there is an element available.
7. Get the next key.

Chapter 12 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is about collections.

Go to the full post

Records

The PL/SQL could create his own data types that in this language are identified by the keyword RECORD.

A record could be created in three ways: basing it on a table data definition; making it as an indipendent brand new type; and basing it on a cursor type definition.

If we want to fetch data from a table, we could create a record matching the table definition. For instance, let's say that we want to work with the COUNTRIES table in the Oracle test hr schema:

declare
l_country countries%rowtype; -- 1.
begin
select *
into l_country -- 2.
from countries
where country_id = 'AR';

dbms_output.put_line(l_country.country_name); -- 3.
exception
when no_data_found then -- 4.
dbms_output.put_line('No data found');
when others then
dbms_output.put_line('Unexpected exception');
end;

1. that's how we define a table based record.
2. we fetch the data through select in our record.
3. that's how we access fields in a record.
4. if SELECT don't find anything, an exception is raised.

No need of duplicating an entire table structure in a record, if that is not necessary. For instance here we create and use a custom record based on the COUNTRIES table, but using only a couple of fields:

declare
type my_country_rt is record ( -- 1.
country_id countries.country_id%type,
country_name countries.country_name%type
);
l_country my_country_rt; -- 2.
begin
select country_id, country_name
into l_country
from countries
where country_id = 'AR';

dbms_output.put_line(l_country.country_name);
exception
when no_data_found then
dbms_output.put_line('No data found');
when others then
dbms_output.put_line('Unexpected exception');
end;

1. That's how we define a brand new record type.
2. And this is the definition of variable of our new record type.

Given a cursor, we could create a record based on it:

declare
cursor l_countries_cur is
select * from countries
where country_id like 'A%';
l_country l_countries_cur%rowtype; -- 1.
begin
open l_countries_cur;
loop
fetch l_countries_cur into l_country;
exit when l_countries_cur%notfound;
dbms_output.put_line(l_country.country_id || ' ' || l_country.country_name);
end loop;
close l_countries_cur;
end;

1. That's the definition of a cursor based record

We have already seen that we could simplify the cursor-record relation using the cursor for loop structure. Here is the previous code rewritten using an implicit cursor based record:

begin
for l_country in (select * from countries where country_id like 'A%')
loop
dbms_output.put_line(l_country.country_id || ' ' || l_country.country_name);
end loop;
end;

Chapter 11 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein tells a lot more than this about records.

Go to the full post