Gossamer Forum
Home : Products : Links 2.0 : Customization :

array_to_hash; the consequences

Quote Reply
array_to_hash; the consequences
Hi,

In add.cgi where links.def is included, I would like to include some records form another database. I modified the script to read the other database, and assign the values. Only array_to_hash will usualy build the records of my job-database with the names of my links-database. (due to links.def)

So I assign the values like: $in{'JOBTITLE'} = $job{$db_cols[3]};

But I'm wondering the following:

- What if I would like to include a number (like: $job{$db_cols[16]}) thats higher then the number of records of my links-database?
- Can I modify array_to_hash so i would not try to build the array with names, but only with numbers; So I'm sure eveything will function normal!

Or am I already overriding the function by using $job{$db_cols[3]} instead of names; so I don't need to worry about anything?!

Hope someone can give me some feedback........


Code:

open (DB, "<$db_job_name") or &cgierr("error in dynamic_form. unable to open db file: $db_job_name. Reason: $!");
LINE: while (<DB>) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
chomp;
@data = &split_decode($_);
if ($data[0] eq $jobid) {
$found = 1;
%job = &array_to_hash (0, @data);
last LINE;
}
}
close DB;
$found or &display ("Unable to display record: $jobid") and return;


$in{'JOBTITLE'} = $job{$db_cols[3]};
Code:
sub array_to_hash {
# --------------------------------------------------------
# Converts an array to a hash using db_cols as the field names.
#
my ($hit, @array) = @_;
my ($i);
return map { $db_cols[$i] => $array[$hit * ($#db_cols+1) + $i++] } @_;
}
Quote Reply
Re: array_to_hash; the consequences In reply to
The problem with referring to column numbers is that if you change those column numbers at any time, then you will have to manually edit the script...

One suggestion is to use record hash....

Like the following:

Code:

$in{'JOBTITLE'} = $rec{'Fieldname'};


Of course, if you change the field names, then the same problem would arise.


Regards,

Eliot Lee
Quote Reply
Re: array_to_hash; the consequences In reply to
But that's exactly why I post this.

The names are taken from links.def (because this file isa included by the script) BUT this routine opens my job-database. So the names defined in links.def are not the names I have in jobs.def. And I can't include 2 def files.

So how to correctly write a sub that will take files from another database?

Quote Reply
Re: array_to_hash; the consequences In reply to
You can require another def file:

Code:

require "/path/to/another.def";


within the sub that you are pulling the values.

Then after you "pull" the values, use undef;.

Regards,

Eliot Lee
Quote Reply
Re: array_to_hash; the consequences In reply to
Wauw, AnthoRules I didn't know that!

Requiring two .def files create nice new possiblities; but how does the undef works exactly That's the part I don't understand (yet).

What I do understand: After reading your post I understood that after some altering I can include $in{'Standard_Field_Names'} and $rec{'Field_Names_from_another_database'} in all my add templates. (add_form, add_succes, and add_error)

So I modified my add.cgi like this:


sub process_form {
# --------------------------------------------------------

.....[ regular add.cgi code here ( not important for this example) ] .....


&get_file_information;

.....[ regular add.cgi code here ( not important for this example) ] .....

# Send the admin an email message notifying of new addition.
&send_email;
# Send the visitor to the success page.
&site_html_add_success;
}
else {
&site_html_add_failure($status);
}
}

sub get_file_information {

require "$db_lib_path/jobs.def";
my (%rec) = &get_record ($in{'JOB_ID'});

}



But it doen't seem to include both the $rec and $in fields in my templates :-(

Quote Reply
include 2 .def files In reply to
 I'm alsow very interested in this feature. I'm now alsow including my second database on a complicated method. So I hope AntroRules can explain this a little bit more; I alsow didn't succceed in including $in and $rec field by their names.

- Chris

Quote Reply
Re: array_to_hash; the consequences In reply to
'But it doen't seem to include both the $rec and $in fields in my templates :-('

Use the following under the sub header:

my %rec = @_;
my %in = @_;




Good Luck!

Glenn
http://cgi-resource.co.uk/pages/links2mods.shtml
Quote Reply
Re: array_to_hash; the consequences In reply to
I'll try!

--- editted ---

I tried but didn't succeed


Because I don't understand the two .def files story I can't troubleshoot this script myself. Therefore I modified my piece of code so I don't have the array_to_hash problem and don't need the two def files.

This is what I did:

Code:
open (DB, "<$db_job_name") or &cgierr("error in dynamic_form. unable to open db file: $db_job_name. Reason: $!");
LINE: while (<DB>) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
chomp;
@data = &split_decode($_);
if ($data[0] eq $jobid) {
$found = 1;
$in{'JOBTITLE'} = $data[3];
$in{'JOBDESCRIPTION'} = $data[8];
$in{'JOBCONTACTNAME'} = $data[11];
last LINE;
}
}
close DB;
$found or &display ("Unable to display record: $jobid") and return;
And now I can just include the standard $in{'Fieldname'} and the $in-tags I made by hand.

Is this the best way or not?

(Please comment this routine so I can improve it if needed.)


PS If someone can explain the 2 .def files and undef story more: Please! Maybe then I could improve this script by using the (standard) get_record feature.
Quote Reply
Re: array_to_hash; the consequences In reply to
Okay... here's a brief explanation:

%db_def is a hash of arrays.
Code:
ID => [0, 'numer', 5, 8, 1, '', ''],
^ ^
key values
You access each value like you would for an array, accept preceding the element position with the hash key.

Code:
$db_def{ID}[0] = key position (0)
$db_def{ID}[1] = content type (numer)
$db_def{ID}[2] = field length (5)
$db_def{ID}[3] = maximum characters (8)
$db_def{ID}[4] = required (1)
$db_def{ID}[5] = default value (null)
$db_def{ID}[6] = regular expression (null)
When data is read into memory, it is put into an array of arrays (that will get turned into hashes)

Code:
@links = ((ID, 1, Title, Blah), (ID, 2, Title, Something));
^ ^
key value
When a record is needed, Links goes through each array, and converts the values into a hash for you to use:

Code:
%rec = @_;
Complicated enough? Smile (Eliot, Alex, if I'm wrong about this please correct me.)

Happy Coding,

--Drew
http://www.FindingHim.com
Quote Reply
Re: array_to_hash; the consequences In reply to
Thank you for your explanation (and your time to post it)

.....but I already understood that part ;-)


So I don't understand why you thought I didn't understand that part. Did I not express myself clearly or didn't you read this thread completely. Anyway.....

I just wanted to change the folllowing part of add.cgi

Code:
# We are processing the form.
if (keys %in != 0) {
&process_form;
}
# Otherwise we are displaying the form (in site_html.pl).
else {
&site_html_add_form();
}
}
into something like:

Code:
# We are processing the form.
if (keys %in != 0) {
&process_form;
}
# Otherwise we are displaying the form (in site_html.pl).
else {
&dynamic_form($in{'REPLY_ID'});
}
}


sub dynamic_form {
my $record = shift;
require "$db_definitions_path/database.def";

if ($record =~ /^\d+$/) {
my (%rec) = &get_record ($record);
($rec{$db_key} eq $record) ?
&site_html_add_form() :
&site_html_add_failure ("Unkown REPLY ID: $in{'REPLY_ID'}");
}
else {
&site_html_add_form();
}

.....so I could use all sorts of $in{} (like standard) and $rec{} for the info out of the database!

Only with this "method" I don't understand the consequences of two .def files and if the possible bugs/errors. And I didn't succeed in including both $in and $rec into my templates.







Quote Reply
Re: array_to_hash; the consequences In reply to
To ds: I'm doing almost the same but did succeed! And I didn't even do anything special with my site_html.pl

To the rest and ds: Smile

I just have:

Code:
sub main {
# --------------------------------------------------------
local (%in) = &get_file_and_form();
# local (%in) = &parse_form(); # TO BYPASS UPLOAD-FEATURE

# We are processing the form.
if ($in{'submit'}) {
&process_form;
}
# Otherwise we are displaying the form (in site_html.pl).
else {
&dynamic_form($in{'UserID'});
}
}

sub dynamic_form {
# --------------------------------------------------------
my $record = shift;
require "users.def";

if ($record =~ /^\d $/) {
my (%rec) = &get_record ($record);
($rec{$db_key} eq $record) ?
&site_html_request_form () :
&site_html_request_form ("default");
}
# Otherwise we are displaying the form (in site_html.pl).
else {
&site_html_request_form ("default");

}

}
.....and now I just can use $rec for all my user-info and $in for all regular data!


BUT NOW I'M WONDERING ABOUT TWO THINGS:

1) Isn't the code of ds quicker, because he only reads the fields out of the database that he needs (like: $data[numer]) This because I have a lot of info from each user and I only need login and nickname. Or does this does effect the speed of scripts?

I'm talking about the following code:

Code:
open (DB, "<$db_job_name") or &cgierr("error in dynamic_form. unable to open db file: $db_job_name. Reason: $!");
LINE: while (<DB>) {
(/^#/) and next LINE;
(/^\s*$/) and next LINE;
chomp;
@data = &split_decode($_);
if ($data[0] eq $jobid) {
$found = 1;
$in{'JOBTITLE'} = $data[3];
$in{'JOBDESCRIPTION'} = $data[8];
$in{'JOBCONTACTNAME'} = $data[11];
last LINE;
}
}
close DB;
$found or &display ("Unable to display record: $jobid") and return;

2) Does the include of two .def files have any effect to other subs, like process_form.

...I there anybody that would like to share his/hes thought about this subject/problem?


ADDED: 22:12

I just found out my site_html.pl doesn't display everything correctly; this because I need the correct .def file to build radio and checkbox field; So how can I make sure my site_html.pl will not be effected by the require "users.def"?



Quote Reply
Re: array_to_hash; the consequences In reply to
Doh! I could have swore that when I read your message the first time that you wanted an explaination of the def hashes, not the def files. (I assume my explanation was right, though?) But I'm not sure exactly what to say about your other question...

Happy Coding,

--Drew
http://www.FindingHim.com
Quote Reply
Re: array_to_hash; the consequences In reply to
Hope somebody van give some feedback ;-)

Til then I assume that including fields from another database with array_to_hash is NOT possible. (See the chrishintz-bug) But on the way I did, you can manualy add fields.