DBD-Sprite

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

	  regices were modified with the "s" option.  Please report anything that 
	  might be broken by this new release!
0.30  Thu Jan 10
	- Fixed bug where specifying a negative number in a "where" clause 
	  as an unbound constant, returned all records and set the field in all 
	  records to that number (ouch!)
	- Fixed bug there double-backslashes in data inserted into a table were 
	  converted to a single backslash.
	- Added better "BLOB" support.  BLOB/LONG/MEMO fields no longer have 
	  default length specified as 5000 and data should no longer be truncated.
	- ADDED ENCRYPTION OPTION!  If the "Crypt::CBC", and "Crypt::IDEA" or 
	  "Crypt::DES" are available, you can connect specifying 
	  "sprite_Crypt => 'IDEA;any_key_string'" (use "DES" in lieu of "IDEA", 
	  if so inclined).  To read in existing unencrypted tables and write them 
	  out encrypted, use "sprite_Crypt => 'encrypt=IDEA;your_key_string'".
	  To read in encrypted databases and write them back unencrypted, use: 
	  "sprite_Crypt => 'decrypt=IDEA;your_key_string'".  Note:  Any method 
	  of encryption that Crypt::CBC supports may be used instead of IDEA or 
	  DES, if you have the module installed.
0.32  Thu Feb 22
	- Fixed bug which prevented one from using single-letter field names.
	  (caught by me).
	- Fixed bug which caused SELECTs to sometimes fail with psuedo-columns and 
	  functions, ie. sequence.NEXTVAL (caught by me).
	- Fixed bug that caused extra "-528:Could not read/write BLOB file" errors 
	  to be displayed after other errors (caught by me).
	- Added "sprite_reclimit" option to permit user to limit number of records 
	  fetched in a single query.

Changes  view on Meta::CPAN

	  caused -517 errors.
	- Added ability to separately specify the field separator string for input 
	  vs output.  Original Sprite supported this, but I always set them to be 
	  the same.  By default they still are.  This became useful to me when 
	  testing XML because I could specify the output field separator as 'XML' 
	  and the input one as whatever my existing table was, read it in and 
	  write it right back out as XML!  The new options are:  sprite_read, 
	  sprite_write, and sprite_field.  The latter sets both to the same thing.
	  sprite_record sets the record separator.
0.35  Thu May 30
	- Made global variable "CBC" an object variable fixing bug which caused 
	  problems when one used both an encrypted database and an unencrypted one 
	  in the same program (caught by me).  
	- Added base-64 encoding to the new XML stuff and fixed up the encoding so 
	  that binary data should now work properly both in and out.  Encoded 
	  fields now have a 'xml:encoding="base64"' attribute.  Note:  the 
	  "MIME::Base64" module is now a prerequisite if using XML.
	- Restored the "sprite_sizelimit" attribute (alias for the "sprite_reclimit" 
	  attribute) for backward compatability sake (I once used this in another 
	  program and DBD::LDAP uses "ldap_sizelimit" - I can't remember why).
0.36  Thu Jun 6

DBDSprite.htm  view on Meta::CPAN

        to 1.

    sprite_CaseFieldNames  (NEW)
        By default, field names are case-insensitive (as they are in Oracle),
        to make field names case-sensitive (as in XML), so that one could
        have two separate fields such as "field1" and "Field1", set this option
        to 1.

    sprite_Crypt
        "0" by defalt.  Specifies that encryption is to be used when storing 
        the data in the flat-file.  To use, download "Crypt::CBC", and one 
        or more of "Crypt::DES", "Crypt::IDEA", or "Crypt::Blowfish".  You 
        can specify using any of the following formats:
        
            sprite_Crypt => 'my key string'
                Use Blowfish encryption.
            sprite_Crypt => 'DES;my key string'
                Use DES encryption.
            sprite_Crypt => 'encrypt=CBC;IDEA;my key string'
                Use IDEA encription, but read in table as unencrypted, then 
                write it out encrypted (great for encrypting previously 
                unencrypted tables).
            sprite_Crypt => 'decrypt=CBC;Blowfish;my key string'
                use Blowfish encryption, but write out table unencrypted. 
                This allows one to fetch an encrypted table and write it back 
                out unencrypted.

    sprite_reclimit  (aka. sprite_sizelimit)
        Allows user to specify the maximum number of records to be returned 
        by a single query.  Default is "0", which permits an unlimited number.

    sprite_StrictCharComp
        CHAR fields are always right-padded with spaces to fill out

DBDSprite.htm  view on Meta::CPAN

		  regices were modified with the "s" option.  Please report anything that 
		  might be broken by this new release!
	<LI>0.30  Thu Jan 10
		<BR>- Fixed bug where specifying a negative number in a &quot;where&quot; clause 
		  as an unbound constant, returned all records and set the field in all 
		  records to that number (ouch!)
		<BR>- Fixed bug there double-backslashes in data inserted into a table were 
		  converted to a single backslash.
		<BR>- Added better &quot;BLOB&quot; support.  BLOB/LONG/MEMO fields no longer have 
		  default length specified as 5000 and data should no longer be truncated.
		<BR>- ADDED ENCRYPTION OPTION!  If the &quot;Crypt::CBC&quot;, and &quot;Crypt::IDEA&quot;, &quot;Crypt::Blowfish&quot; or 
		  &quot;Crypt::DES&quot; are available, you can connect specifying 
		  &quot;sprite_Crypt => 'IDEA;any_key_string'&quot; (use &quot;DES&quot; in lieu of &quot;IDEA&quot;, 
		  if so inclined).  To read in existing unencrypted tables and write them 
		  out encrypted, use &quot;sprite_Crypt => 'encrypt=IDEA;your_key_string'&quot;.
		  To read in encrypted databases and write them back unencrypted, use: 
		  &quot;sprite_Crypt => 'decrypt=IDEA;your_key_string'&quot;.  Note:  Any method 
		  of encryption that Crypt::CBC supports may be used instead of IDEA or 
		  DES, if you have the module installed.
	<LI>0.31  Thu Feb 22
		<BR>- Fixed bug which prevented one from using single-letter field names.
		  (caught by me).
		<BR>- Fixed bug which caused SELECTs to sometimes fail with psuedo-columns and 
		  functions, ie. sequence.NEXTVAL (caught by me).
		<BR>- Fixed bug that caused extra &quot;-528:Could not read/write BLOB file&quot; errors 
		  to be displayed after other errors (caught by me).
		<BR>- Added code so &quot;darwin&quot; (new Mac-OS) would use unix &quot;/&quot; separator, was 
		  using WinDOwS separators (&quot;\\&quot;) for directories (caught by Thabo).

DBDSprite.htm  view on Meta::CPAN

		  caused -517 errors.
		<BR>- Added ability to separately specify the field separator string for input 
		  vs output.  Original Sprite supported this, but I always set them to be 
		  the same.  By default they still are.  This became useful to me when 
		  testing XML because I could specify the output field separator as 'XML' 
		  and the input one as whatever my existing table was, read it in and 
		  write it right back out as XML!  The new options are:  sprite_read, 
		  sprite_write, and sprite_field.  The latter sets both to the same thing.
		  sprite_record sets the record separator.
	<LI>0.35  Thu May 30
		<BR>- Made global variable "CBC" an object variable fixing bug which caused 
	  	  problems when one used both an encrypted database and an unencrypted one 
	  	  in the same program (caught by me).  
		<BR>- Added base-64 encoding to the new XML stuff and fixed up the encoding so 
		  that binary data should now work properly both in and out.  Encoded 
		  fields now have a 'xml:encoding="base64"' attribute.  Note:  the 
		  "MIME::Base64" module is now a prerequisite if using XML.
		<BR>- Restored the "sprite_sizelimit" attribute (alias for the "sprite_reclimit" 
		  attribute) for backward compatability sake (I once used this in another 
		  program and DBD::LDAP uses "ldap_sizelimit" - I can't remember why).
	<LI>0.36  Thu Jun 6

README  view on Meta::CPAN

        to 1.  (read-only after "connect")

    sprite_CaseFieldNames  (NEW)
        By default, field names are case-insensitive (as they are in Oracle(tm)),
        to make field names case-sensitive, so that one could have two 
        separate fields such as "test" and "TEST" in the same table, set 
        this option to 1.  (read-only after "connect")

	sprite_Crypt
		"0" by defalt.  Specifies that encryption is to be used when storing 
		the data in the flat-file.  To use, download "Crypt::CBC", and one 
		or more of "Crypt::DES", "Crypt::IDEA", or "Crypt::Blowfish".  You 
		can specify using any of the following formats:
		
			sprite_Crypt => 'my key string'
				Use Blowfish encryption.
			sprite_Crypt => 'DES;my key string'
				Use DES encryption.
			sprite_Crypt => 'encrypt=CBC;IDEA;my key string'
				Use IDEA encription, but read in table as unencrypted, then 
				write it out encrypted (great for encrypting previously 
				unencrypted tables).
			sprite_Crypt => 'decrypt=CBC;Blowfish;my key string'
				use Blowfish encryption, but write out table unencrypted. 
				This allows one to fetch an encrypted table and write it back 
				out unencrypted.

	sprite_reclimit
		 Allows user to specify the maximum number of records to be returned 
		 by a single query.  Default is "0", which permits an unlimited number.

    sprite_StrictCharComp
        CHAR fields are always right-padded with spaces to fill out

lib/DBD/Sprite.pm  view on Meta::CPAN

I<sprite_StrictCharComp> => 0 | 1

		CHAR fields are always right-padded with spaces to fill out 
		the field.  Old (pre 5.17) Sprite behaviour was to require the 
		padding be included in literals used for testing equality in 
		"where" clauses. 	I discovered that Oracle and some other databases 
		do not require this when testing DBIx-Recordset, so Sprite will 
		automatically right-pad literals when testing for equality.  
		To disable this and force the old behavior, set this option to 1.
		
I<sprite_Crypt> => [encrypt=|decrypt=][Crypt]::CBC;][[IDEA[_PP]|DES[_PP]|BLOWFISH[_PP];]keystring
	
		Optional encryption and/or decryption of data stored in tables.  By 
		omitting "encrypt=" and "decrypt=", data will be decrypted when read 
		from the table and encrypted when written to the table using the 
		"keystring" as the key.
		
I<sprite_forcereplace> => 0 | 1
	
		This option forces the table file to first be deleted before being 
		overwritten.  Default is 0 (do not delete, just overwrite it).  This 

lib/JSprite.pm  view on Meta::CPAN

		lasterror    => 0,     #JWT:  ADDED FOR ERROR-CONTROL
		lastmsg      => '',
		CaseTableNames  => 0,    #JWT:  19990991 TABLE-NAME CASE-SENSITIVITY?
		LongTruncOk  => 0,     #JWT: 19991104: ERROR OR NOT IF TRUNCATION.
		LongReadLen  => 0,     #JWT: 19991104: ERROR OR NOT IF TRUNCATION.
		RaiseError   => 0,     #JWT: 20000114: ADDED DBI RAISEERROR HANDLING.
		silent       => 0,
		dirty			 => 0,     #JWT: 20000229: PREVENT NEEDLESS RECOMMITS.
		StrictCharComp => 0,    #JWT: 20010313: FORCES USER TO PAD STRING LITERALS W/SPACES IF COMPARING WITH "CHAR" TYPES.
		sprite_forcereplace => 0,  #JWT: 20010912: FORCE DELETE/REPLACE OF DATAFILE (FOR INTERNAL WEBFARM USE)!
		sprite_Crypt => 0,  #JWT: 20020109:  Encrypt Sprite table files! FORMAT:  [[encrypt=|decrypt=][Crypt]::CBC;][[IDEA[_PP]|DES]_PP];]keystr
		sprite_reclimit => 0, #JWT: 20010123: PERMIT LIMITING # OF RECORDS FETCHED.
		sprite_sizelimit => 0, #JWT: 20010123: SAME AS RECLIMIT, NEEDED BOR BACKWARD COMPAT.
		sprite_actlimit => 0, #JWT: 20010123: SAME AS RECLIMIT, NEEDED BOR BACKWARD COMPAT.
		dbuser			=> '',      #JWT: 20011026: SAVE USER'S NAME.
		dbname			=> '',      #JWT: 20020515: SAVE DATABASE NAME.
		CBC			=> 0,       #JWT: 20020529: SAVE Crypt::CBC object, if encrypting!
		sprite_xsl	=> '',      #JWT: 20020611: OPTIONAL XSL TEMPLATE FILE.
		sprite_CaseFieldNames => 0,  #JWT: 20020618: FIELD-NAME CASE-SENSITIVITY?
		sprite_lastsequence => '',   #JWT: ADDED 20020905 TO SUPPORT DBIx::GeneratedKey!
		sprite_nocase => 0,    #JWT: ADDED 20040323 TO SUPPORT CASE-INSENSITIVE WHERE-CLAUSES LIKE LDAP.
		                       #NOTE - ONLY CURRENTLY FOR "LIKE/NOT LIKE" (VALUE=1|'L)!
		                       #MAY ADD OTHER VALUES LATER!
		ASNAMES => {},         #ADDED 20040913 TO SUPPORT "AS" IN SELECTS.
	    };

    $self->{separator} = { Unix  => '/',    Mac => ':',   #JWT: BUGFIX.

lib/JSprite.pm  view on Meta::CPAN

{
    my $self = shift;

    $sprite_user = $self->{'dbuser'};   #ADDED 20011026.
    $self->define_errors;
    $self->set_os ($^O) if (defined $^O);
	if ($self->{sprite_Crypt})  #ADDED: 20020109
	{
		my (@cryptinfo) = split(/\;/, $self->{sprite_Crypt});
		unshift (@cryptinfo, 'IDEA')  if ($#cryptinfo < 1);
		unshift (@cryptinfo, 'Crypt::CBC')  if ($#cryptinfo < 2);
		$self->{sprite_Crypt} = 1;
		$self->{sprite_Crypt} = 2  if ($cryptinfo[0] =~ s/^encrypt\=//i);
		$self->{sprite_Crypt} = 3  if ($cryptinfo[0] =~ s/^decrypt\=//i);
		$cryptinfo[0] = 'Crypt::' . $cryptinfo[0]  
				unless ($cryptinfo[0] =~ /\:\:/);
		eval "require $cryptinfo[0]";
	    if ($@)
	    {
			$errdetails = $@;
			$self->display_error (-526);
		}
		else
		{
		    eval {$self->{CBC} = Crypt::CBC->new($cryptinfo[2], $cryptinfo[1]); };
		    if ($@)
		    {
				$errdetails = "Can't find/use module \"$cryptinfo[1].pm\"? ($@)!";
				$self->display_error (-526);
			}
		}
	}
	return $self;
}

lib/JSprite.pm  view on Meta::CPAN

				{
					if ($coltypes[$i])   #BLOB REF.
					{
						$code = qq|\$rawvalue = $values->{$columns[$i]};|;
						eval $code;
						$blobfid = $self->{directory}.$self->{separator}->{ $self->{platform} }
						.$self->{table}.'_'.$_->{$columns[$i]}."_$$.tmp";
						if (open(FILE, ">$blobfid"))
						{
							binmode FILE;
							if ($self->{CBC} && $self->{sprite_Crypt} <= 2)  #ADDED: 20020109
							{
								print FILE $self->{CBC}->encrypt($rawvalue);
							}
							else
							{
								print FILE $rawvalue;
							}
							close FILE;
						}
						else
						{
							$errdetails = "$blobfid: ($?)";

lib/JSprite.pm  view on Meta::CPAN

				my $randblobfid;
				do {
					$randblobid = int(rand(99999));
					$randblobfid = $self->{directory}
							.$self->{separator}->{ $self->{platform} }
							.$self->{table}."_${randblobid}_$$.tmp";
				} while (-e $randblobfid);
				if (open(FILE, ">$randblobfid"))
				{
					binmode FILE;
					if ($self->{CBC} && $self->{sprite_Crypt} <= 2)  #ADDED: 20020109
					{
						print FILE $self->{CBC}->encrypt($v);
					}
					else
					{
						print FILE $v;
					}
					close FILE;
					$hash->{$column} = $randblobid;
				}
				else
				{

lib/JSprite.pm  view on Meta::CPAN

		return (-509);
    }
}						    

sub write_file
{
    my ($self, $new_file) = @_;
    my ($i, $j, $status, $loop, $record, $column, $value, $fields, $record_string);
	my (@keyfields) = split(',', $self->{key_fields});  #JWT: PREVENT DUP. KEYS.
	return ($self->display_error (-531) * -531)
			if (($self->{_write} =~ /^xml/io) && $self->{CBC} && $self->{sprite_Crypt} <= 2);

    local (*FILE, $^W);
	local ($/);
	if ($self->{CBC} && $self->{sprite_Crypt} <= 2)  #ADDED: 20020109
	{
		$/ = "\x03^0jSp".$self->{_record};    #(EOR) JWT:SUPPORT ANY RECORD-SEPARATOR!
	}
	elsif ($self->{_write} !~ /^xml/io)
	{
		$/ = $self->{_record};    #JWT:SUPPORT ANY RECORD-SEPARATOR!
	}

    $^W = 0;

lib/JSprite.pm  view on Meta::CPAN

				#$fields .= ')' . $self->{_write};
				$fields .= ')';
			}
			$fields .= '='. ${$self->{defaults}}{${$self->{order}}[$i]}  
					if (length(${$self->{defaults}}{${$self->{order}}[$i]}));
			$fields .= $self->{_write};
		}
		$fields =~ s/$self->{_write}$//;
	}

	if ($self->{CBC} && $self->{sprite_Crypt} <= 2)  #ADDED: 20020109
	{
		print FILE $self->{CBC}->encrypt($fields).$/;
	}
	else
	{
		print FILE "$fields$/";
	}
	my $rsinit = ($self->{_write} =~ /^xml/io) ? "  <row>\n" : '';
	my $rsend = $rsinit ? "  </row>\n" : '';

	for ($loop=0; $loop < $reccnt; $loop++) {
		#++$loop1;

lib/JSprite.pm  view on Meta::CPAN

			$value =~ s/$self->{_record}/\x02\^0jSpR1tE\x02/gso;   #PROTECT EMBEDDED RECORD SEPARATORS.
			$value =~ s/$self->{_write}/\x02\^1jSpR1tE\x02/gso;   #PROTECT EMBEDDED RECORD SEPARATORS.
			$record_string .= $rsinit ? (&xmlescape($column,$value)."\n") 
					: "$self->{_write}$value";
	    }

	    #$record_string =~ s/^$self->{_write}//o;  #CHGD TO NEXT LINE 20010917.
	    $record_string =~ s/^$self->{_write}//s;
	    $record_string .= $rsend;

		if ($self->{CBC} && $self->{sprite_Crypt} <= 2)  #ADDED: 20020109
		{
			print FILE $self->{CBC}->encrypt($record_string).$/;
		}
		else
		{
		    print FILE "$record_string$/";
		}
	}
	if ($rsend)
	{
		$rsend = " </select>\n</database>\n";
		if ($self->{CBC} && $self->{sprite_Crypt} <= 2)  #ADDED: 20020109
		{
			print FILE $self->{CBC}->encrypt($rsend).$/;
		}
		else
		{
		    print FILE "$rsend$/";
		}
	}
	close (FILE);

	my (@stats) = stat ($new_file);
	$self->{timestamp} = $stats[9];

lib/JSprite.pm  view on Meta::CPAN

			return "   <$_[0]>$_[1]</$_[0]>";
		}	
	}
}

sub load_database 
{
    my ($self, $file) = @_;

	return -531 
			if (($self->{_read} =~ /^xml/io) && $self->{CBC} && $self->{sprite_Crypt} <= 2);

    my ($i, $header, @fields, $no_fields, @record, $hash, $loop, $tp, $dflt);
    local (*FILE);
	local ($/);
	if ($self->{CBC} && $self->{sprite_Crypt} != 2)  #ADDED: 20020109
	{
		$/ = "\x03^0jSp".$self->{_record};    #JWT:SUPPORT ANY RECORD-SEPARATOR!
	}
	else
	{
		$/ = $self->{_record};    #JWT:SUPPORT ANY RECORD-SEPARATOR!
	}

	########$file =~ tr/A-Z/a-z/  unless ($self->{CaseTableNames});  #JWT:TABLE-NAMES ARE NOW CASE-INSENSITIVE!
	#$thefid = $file;

lib/JSprite.pm  view on Meta::CPAN

			eval { flock (FILE, $JSprite::LOCK_EX) || die };
	
			if ($@)
			{
				$self->lock || $self->display_error (-515)  if ($@);
			}
		}
		$_ = <FILE>;
		chomp;          #JWT:SUPPORT ANY RECORD-SEPARATOR!
		my $t = $_;
		$_ = $self->{CBC}->decrypt($t)  if ($self->{CBC} && $self->{sprite_Crypt} != 2);  #ADDED: 20020109
		return -527  unless (/^\w+\=/o);   #ADDED 20020110

		($header)  = /^ *(.*?) *$/o;
		#####################$header =~ tr/a-z/A-Z/;   #JWT  20000316
	    #@fields    = split (/$self->{_read}/o, $header);  #CHGD TO NEXT LINE 20021216.
		@fields    = split (/\Q$self->{_read}\E/, $header);
		$no_fields = $#fields;

		undef %{ $self->{types} };
		undef %{ $self->{lengths} };

lib/JSprite.pm  view on Meta::CPAN

			${$self->{scales}}{$fields[$i]} = '0'  unless (${$self->{scales}}{$fields[$i]});

			# (JWT 8/8/1998) $self->{use_fields} .= $column_string . ',';    #JWT
			$self->{use_fields} .= $fields[$i] . ',';    #JWT
		}

		while (<FILE>)
		{
			chomp;
			$t = $_;
			$_ = $self->{CBC}->decrypt($t)  if ($self->{CBC} && $self->{sprite_Crypt} != 2);  #ADDED: 20020109

			next unless ($_);

			#@record = split (/$self->{_read}/s, $_);   #CHGD. TO NEXT LINE 20021216
			@record = split (/\Q$self->{_read}\E/s, $_);

			$hash = {};

			for ($loop=0; $loop <= $no_fields; $loop++)
			{

lib/JSprite.pm  view on Meta::CPAN

	else
	{
		local (*FILE);
		local ($_);
		local ($/) = $self->{_record};    #JWT:SUPPORT ANY RECORD-SEPARATOR!
	
		open(FILE, $self->{file}) || return -501;
		binmode FILE;         #20000404
		if ($self->{_read} =~ /^xml/io)
		{
			return -531  if ($self->{CBC} && $self->{sprite_Crypt} <= 2);
			return -532  unless ($XMLavailable);
	
			my $xs1 = XML::Simple->new();
			my $xmltext = '';
			my $xmldoc;
#			eval {$xmldoc = $xs1->XMLin($self->{file}, suppressempty => undef); };
			while (<FILE>)
			{
				last  if (/^\s*\<row.*\>\s*$/o);
				$xmltext .= $_;



( run in 1.080 second using v1.01-cache-2.11-cpan-df04353d9ac )