Up to [Local Repository] / interchange / lib / Vend
Request diff between arbitrary revisions
Keyword substitution: kv
Default branch: MAIN
Allow explicit manual table exports even when NoExportExternal is enabled. This could be done from any invocation of Vend::Data::export_database, but is here done only from the [backup-database] tag used in the admin.
Extend set_slice() to allow control of upsert behavior.
Calls to set_slice() are forced to use the upsert model of data
manipulation. This can be a highly desirable editing model, but it also
has disadvantages, particularly in the context of the 'set' and 'autoset'
form actions, which imply--but don't enforce--a distinction between
insert and update at the data-storage level.
The effects on insert can be particularly insidious, where one faces
having the assumed behavior on duplicate primary keys thwarted by a
surreptitious conversion to a SQL update. In such an instance, instead of
existing data being protected by a duplicate PK error, the extant record
is replaced by the data from the insert. Detecting this condition,
particularly on a large table, is virtually impossible.
While the results of an update-to-insert adjustment are more benign, it
still presents a nuisance if a strict update is intended. To correct it,
one merely needs to delete the newly created, unanticipated row, and such
behavior does not destroy existing data.
To enforce update or insert, set_slice()'s $key arg can be optionally
passed as an array ref, essentially replacing the existing call:
set_slice($key,$fary,$vary)
with
set_slice([$opt, $key],$fary,$vary)
where $opt->{dml} is set to the desired value. $opt as a hash ref is
used so that any possible future opt-style params can simply be loaded
into the existing calling structure.
Change details:
* Default behavior for set_slice() is 'upsert'. If you do nothing to
your code or catalog, the behavior remains unchanged.
* $opt->{dml} can be 'insert', 'update', or anything else. If it's
anything else, it has no specific behavior currently. It defaults the
value 'upsert' just to be somewhat self-documenting and open up the
possibility of behaviors based on that value in the future.
* Despite the decision to key it off of 'dml', this has no effect on
deletes. Deletes have no ambiguous behavior, reflected in the fact that
deletes have their own dedicated method.
* Change only has core impact when processing requests through
Vend::Data::update_data(). However, any direct calls to set_slice() may
avail themselves of the new feature simply by overloading the $key arg
in the same fashion.
* Behavior of Vend::Data::update_data() can be in three modes,
controllable by the new 'dml' pragma.
+ No pragma setting works in current mode, with upsert behavior.
+ Pragma 'dml=preserve' restricts inserts to insert-only, but allows
the fall-through behavior from update to insert. As the name preserve
implies, it means no existing data can be clobbered.
The advantage to preserve is the easy use of set_slice() as a
record-cloning operation. In the table editor, one can clone a
record by simply changing the PK. Without this behavior, one must
completely re-enter existing data to the new key's name to clone.
+ Pragma 'dml=strict' forces update or insert to only perform the
requested action.
Various minor UTF-8 changes.
Correct attribution of &Vend::CharSet::display_chars (which is from
perluniintro manpage).
Enable localization of an error string.
Match content type more tightly in 2 spots ("text" is only trustworthy
in the MIME major type, not minor, and even that may be a stretch).
Simplify request method matching in a few places for readability and a
(trivial) performance benefit.
Use conventional $c lexical instead of $g for catalog hashref.
Fix tab/space differences to match context.
Update copyrights of files changed in 2008.
Add new database feature AUTO_NUMBER_FILE.
This allows specifying a nonstandard location and/or filename for a table's
default counter file.
Can also be used to share a counter file across multiple tables.
Usage example in catalog.cfg:
Database area AUTO_NUMBER_FILE counters/generic.autonumber
Allow empty field changes to stick, fixing "(none)" image selections. Fix by David Christensen <david@endpoint.com>. Same problem as mentioned by Cameron Prince on interchange-users 2007-02-10, but this fix covers more cases.
New Free Software Foundation Address in headers of various files
New Free Software Foundation Address in headers of various files
Add new catalog directives: NoExport __TABLENAME__ NoExportExternal Yes These prevent any export of some or all SQL tables to products/*.txt from being done, to stop clutter in products/ from auto-export which helps make the products/ directory nicer to use under version control. Note that this makes the admin export function silently do nothing for SQL tables, though it still works for GDBM tables. With help from Mark Johnson <mark@endpoint.com>.
Remove redundant check, presumably a debugging leftover.
* Fix attribute-based pricing for options. * Add ability to set price to zero with mv_price by checking for "FREE" value. Previously, the zero is returned and ignored for price chain purposes. * Allow setting of values in data to "undef" in field by setting <input type="hidden" name="mv_data_undef:field" value="1">
really log name of non-existent database
* Refine error message to possibly point to problem.
Fix typo in sub call.
Fix typo in sub call.
* Add lockout to list of SpecialSub routines allowed.
* If user-configured lockout routine returns true, it replaces the
current routine completely. If it returns false, the normal one
is run as well.
* Move the logging out of Vend::Dispatch to the do_lockout routine, so
that you can avoid the log entry if your user-configured routine handles
the lockout.
* Make the number of seconds for robot reset adjustable from its
current hardcoded 30:
Limit lockout_reset_seconds
Maybe that should be robot_reset_seconds, I don't know.
* Change use of $Vend::Cfg->{Limit}{member} to $::Limit->{member}. As
Limit is used in iterative routines like chain_cost, this should
improve performance.
Remove antiquated [sql] tag. To be noted in UPGRADE document.
* Add logic to have AutoModifier work for matrix items. Only works for the non-table, non-foreign key call version, i.e. AutoModifier modifier or AutoModifier modifier=field It will look in the mv_ib first, then the first then second products file, for both the code and the mv_sku. This might not be completely what would always be wanted, since it has the precedence: mv_ib->code mv_ib->mv_sku products->code products->mv_sku variants->code variants->mv_sku It is important in this case to make sure you have the table set in the item, as otherwise products->sku will shadow variants->code.
* Improve ability of AutoModifier, make consistent in both places where it can be set. * Current variations: AutoModifier category AutoModifier outboard:category AutoModifier outboard:category:foreign all stay the same -- only difference is that :: is now accepted same as :. * New variation: AutoModifier attribute=table:column AutoModifier attribute=table:column:foreign is accepted. This removes the requirement that the attribute be named the same thing as the table column. * Added regression test that checks all of the above. * Will look for existing documentation to update. * Your regression tests will require a "rm products/products2.sql" to update the data for that table.
Removed duplicate test.
* Don't read salestax.asc if in "multi" mode. * Correct package of routine.
* Change imagehelper routine and its accompanying Data.pm routine to allow it to rename the image to match a field name. Noticed when showing a new user the item input that they had no non-manual way to get the rightly named image up there -- of course they had saved their image with some long quote-filled name. If you set the extended.name_from_field to "sku", it will automatically rename "Some very long name, it's a Windows thing.jpg" to 00001.jpg (or whatever the SKU is).
* Prevent a Global database from instantiating $C and screwing up configuration. * Allow setting of no-import status within the table config instead of the action-at-a-distance of NoImport. Allows global database tables to control their own destiny.
* We had been running without warnings so long, we had gotten a bit sloppy
in our code in some places.
Because we do lots of uninitialized hash member stuff with arrays
of fields and $opt, it is basically unreasonable for us to run with
the "use of uninitialized variable" warnings. Because we do a fair
amount of numerical comparisons on empty string values, it seemed
unreasonable to run with "string value in numeric gt" enabled.
Also, because Safe, HTML::Entities, and some other modules have
these checks enabled, page code is bound to have warnings issued
no matter what you do.
It seems better to run with some warnings enabled so that we can
catch bad code practice.
So I have made the code run without warnings prior to and after
interpolate_html(), and turned off warnings by default in the
page code.
If it is desirable to turn on warnings for pages, you can use
[pragma perl_warnings_in_page] and see warnings for that page
(or by default if you put in catalog.cfg).
* In general these changes are:
no warnings qw(uninitialized numeric);
in most pages.
* Add $::Pragma->{perl_warnings_in_page}.
* Remove defined checks when simple set tests will do.
* Streamline some code.
* Various variable initializations and tests to avoid warnings.
Terminate a statement with a semicolon for standard style, even though it's syntactically correct at the end of a block.
Optimization to item_price routine: Don't worry about the database the item comes from unless using PriceField, since it doesn't matter otherwise. This allows pricing to work when a product isn't in ProductFiles as long as the CommonAdjust can return a valid price.
Add a new database configuration parameter, POSTEXPORT, which allows calling one or more subs or globalsubs after each time that database is exported. Sub is called with database name, exported filename (absolute path), and an options hash consisting of the options given to the export call and values for 'delim' and 'record_delim' for structuring the file pointed to by filename. For example, it could be used to send an email notification, make a log file entry, or do postprocessing on the exported text file. Written and contributed by Ethan Rowe <ethan@endpoint.com> (with a little tweaking by me).
( Continuation of previous changes to these files, inadvertently committed. ) * Spreadsheets can now do file upload, including those linked inside another table.
* Allow table editor to set mv_return_table if not already set, ensures that a linked spreadsheet won't command the table upon return to the select page. * Allow a field's restrict_allow to be set to control expansion of append/prepend values. * Make ui_wizard_fields control when ui_data_fields not set. Used to always come from ui_data_fields.
* Skip uploading blob files as well as standard {image,upload}helper
files/filenames.
* Improve self-contained database definitions by allowing field names to come directly from the CREATE_EMPTY_TXT parameter: Database foo CREATE_EMPTY_TXT code description bar baz This prevents problems with later SQL "alter table ...." statements not being acknowleged by IC because the NAME parameter does not match the NAME array returned by DBI.
* Add ability for Vend::Data::update_data to store filename and file size info in one upload. Adds the variable definitions: mv_data_file_name_to_$name mv_data_file_size_to_$name For instance, if you do: <INPUT TYPE=hidden NAME="mv_data_file_name_to_body" VALUE="filename"> <INPUT TYPE=hidden NAME="mv_data_file_size_to_body" VALUE="size"> <INPUT TYPE=hidden NAME="mv_data_file_field" VALUE="body"> <INPUT TYPE=file NAME="body"> the uploaded file would be stored to the "body" field, its name to "filename", and its size to "size". Size is a simple integer with all its implied limits. In actual practice HTTP server timeouts and browser file upload limits will ensure the value is large enough. * Add new uploadblob widget with core and meta-editor support. If you have a BLOB field and want to upload files to it, select the "uploadblob=File upload to BLOB" widget. It will present a file upload widget, and provide the proper fields to do the upload. If you select the extended.size_to = <fieldname> option in the meta editor, the size of the uploaded file will be stored to <fieldname>. Ditto for extended.name_to, which stores the file name (minus prepending path) to <fieldname>. For example, you might do: [display type=uploadblob name=body size_to=size name_to=filename ] This will produce: <INPUT TYPE=hidden NAME="mv_data_file_name_to_body" VALUE="filename"> <INPUT TYPE=hidden NAME="mv_data_file_size_to_body" VALUE="size"> <INPUT TYPE=hidden NAME="mv_data_file_field" VALUE="body"> <INPUT TYPE=file NAME="body"> * Add ability to define your widget types for display in the meta editor in the Variable UI_WIDGET_TYPES. Includes metadata formatting for the Preferences editor.
* Change MULTIPLE_KEYS to COMPOSITE_KEY for better intuitiveness.
* Add new Class DBI_CompositeKey which allows multiple-key tables to
be used in Interchange in the majority of ways other tables are
used.
Setup is simple. Just use a normal DBI looking table, then
add
Database foo MULTIPLE_KEYS key1 key2 key3
This implies:
Database foo Class DBI_CompositeKey
If you have not already set up the table as a DBI type
(i.e. "Database foo foo.txt dbi:mysql:foobase") then
this will fail.
You should definitely have a COLUMN_DEF for each key. CREATE_SQL
or using NoImport works fine, too.
If you want a unique constraint you have to add it. If you
don't have unique set, you may get anomalous behavior.
-- Keys are passed via arrays, hashes, or null-separation. For
instance:
[data table=foo col=value1 key.0=foo key.1=bar key.2=baz]
[data table=foo col=value1 key.key1=foo key.key2=bar key.key3=baz]
[data table=foo col=value1 key=` join "\0", qw/foo bar baz/`]
All three of the above will return the same thing, as will:
[perl tables=foo]
my $db = $Db{foo};
my @key = qw/foo bar baz/;
my %key = (
key1 => 'foo',
key2 => 'bar',
key3 => 'baz',
);
my $try1 = $db->field(\@key, 'value1');
my $try2 = $db->field(\%key, 'value1');
my $try3 = $db->field( join("\0", @key), 'value1');
if($try1 eq $try2 and $try1 eq $try3) {
return "Access methods returned same value.";
}
else {
return "ERROR: Access methods returned differing values.";
}
[/perl]
-- [import-fields table=foo] works, but the {cleanse} option is
not allowed.
-- [import table=foo ...] works.
-- Exports work.
-- Imports from text files work, i.e. removing .sql file.
-- Table editor works.
-- Flex-select works. There is not as yet a batch delete, but that
should be possible in the future. "Edit keys in sequence" is unlikely
to ever work.
-- Autonumbering and AUTO_SEQUENCE are obviously moot.
-- $db->set_slice(), $db->get_slice work. So does $db->delete_record().
All use the same key types as other access methods.
-- $db->set_row() works, but doesn't do the one-field insert behavior.
Probably a plus. 8-) It should set _Default_ary, but that is not
tested.
* Add ability to control directory creation and umask of uploaded files. Automatic creation of directory: [set mv_auto_create_dir]1[/set] The umask for creation operation: [set mv_create_umask]02[/set]
* Prevent spurious Database error when in PreFork mode. While I am not certain, I think it is caused by the fake "mv_null" database that Vend::Table::Editor uses.
* Add ability to export only portions of tables based on a where= parameter.
Only works for DBI tables at the current time.
If the where parameter is a scalar, just passed as a "WHERE" clause,
i.e.
[export table=products where="prod_group='Ladders'"]
You can pass anything that won't cause a syntax error, even including
an "order by" or "limit".
If you want to pass multiple things, or not worry about quoting,
you can do:
[export table=products where.prod_group=Ladders]
The normal caveats for hash parameters apply, i.e. you cannot
do:
where.prod_group="[cgi foo]"
You *can* do:
where.prod_group=`$Tag->cgi('foo')`
or
where.prod_group=`$CGI->{foo}`
Normal DBI quoting is always done, so you don't include quotes.
Allow multiline values for [scratch mv_data_enable].
* Fix problem where intervening image fields were not being set empty on upload. * Localize an error message.
update_data: removed unused variables and corrected variable references in debug statements
* Remove extraneous POD entries.
Various minor cleanup, prevents warnings on startup.
* Remove extra meta_record routine and change references to
UI::Primitive::meta_record to Vend::Table::Editor::meta_record.
* Delete {Source} value from $Vend::Cfg to save memory.
* Remove unused stub Vend::Data::dbref.
* Change Vend::Util::dbref to be a simple pointer to
Vend::Data::database_exists_ref. Remove extra "my $loc".
* Remove improperly exported parse_locale routine from Vend::Util.
(Another parse_locale in Vend::Config, and all calls in the code
contain package reference.)
* Update dont_warn() routine to only include need variables/handles.
* Remove "prime" of sort routine in Vend::Search no longer necessary
now that Perl 5.005 is not supported.
The great copyright, email address, URL, and version update.
* Add new Vend::File module with minimal functions. * Relocate following routines (and their subsidiaries) from Vend::Util: canonpath catdir catfile exists_filename file_modification_time file_name_is_absolute get_filename lockfile path readfile readfile_db set_lock_type unlockfile writefile Added stubs so that package-based calls to those routines will not break software. * Added CatalogUser directive that allows setting in interchange.cfg of allowed username that is used for access to absolute-path names. CatalogUser foundation joe CatalogUser reports jane This sets the user for allowed_file() for further read/write checks based on username. * Created allowed_file() routine and replaced all current inline checks for NoAbsolute with call to that routine. It behaves as: NoAbsolute is No: all files are accessible, always Allowed for read/write: Path name is relative with no .. Path name is absolute but in the catalog directory Path name is absolute but in a TemplateDir Allowed for read: CatalogUser set to a valid username and file is readable by that user CatalogUser set to a valid username and file is readable by a group containing that user Allowed for write: CatalogUser set to a valid username and file is writable by that user CatalogUser set to a valid username and file is writable by a group containing that user * Changed display_special_page so that special page entries with ../ will not break things. * TODO: -- Code read for open() calls. -- Code read for chmod() calls. -- Code read for unlink() calls. * Passes all regression tests; takes an order on foundation; runs UI including file navigator.
* Prevent NOT NULL errors for data that is actually supposed to be defined.
Prevent internal server error if quantity pricing row cannot be found for whatever reason.
* Major update to product options. * Options are now modular in much the same way as Vend::Payment is. You can add an unlimited number of option types simply by dropping a module into Vend::Options. * By default, the old 4.8 style options are in force, implemented with Vend::Options::Old48. If you add this to catalog.cfg (in etc/after.cfg in foundation): OptionsEnable option_type The "option_type" names a field in the products file which controls the option type. This enables new-style options. It can also be in a specific table and field, ala AutoModifier: OptionsEnable table:field Indeed, this is added to AutoModifer after catalog.cfg. * There are two new-style options included: Vend::Options::Matrix Vend::Options::Simple These are equivalent to the current matrix and simple options. * Options behavior is controlled in catalog.cfg by a locale-style multiple hash (ala UserDb or Route): Options Matrix sort o_sort,o_group Options Matrix variant_table my_variants * To find and add a new option type, simply set something in catalog.cfg: Options MyOptions table my_options That will cause a require of Vend::Options::MyOptions. * The matrix products have been moved to the "variants" table. * The options table contains options for both Matrix and Simple types, but only fields for building those simple-type options (which are used to generate variants for Matrix). The followign fields have been removed from options: differential mv_shipmode o_enable o_exclude o_footer o_header o_include o_master o_matrix o_modular phantom volume weight * The variants table is a subset of the fields in products. * The admin page for each option style is defined in its admin_page routine, usually an include from inclued/Options/OptionType. * size and color fields removed from products table, option_type added.
A few minor things: * Have NonTaxableField check all ProductFiles tables for the field if needed, instead of just the one in mv_ib or the first ProductFiles table. This allows NonTaxableField to work with options when the base product has a nontaxable field, but the options table has no nontaxable field (as in Foundation). This should have no effect on people using NonTaxableField the standard way. * Add option to product_common and item_common that allows an empty field to be returned. In effect this option means "give me the value of this field from the first ProductFiles table that has the field at all" instead of "give me the first true value from a ProductFiles table that has the field". * Optimize item_common a bit by looking at each table only once.
updated LINUXIA branch to 4.9 sources in order to use it as testbed again
Update copyright dates.
* Support sparsely-populated quantity pricing tables. * Fix bug in field name ranges in CommonAdjust where q99..q101 was handled as a Perl alphanumeric range q99, r00, r01, r02, etc. instead of q99, q100, q101. * Add regression test for these changes.
merged changes 2.20 vs 2.21 +++ 2.21 +++ this should fix a longstanding bug where Interchange get stuck into an infinite loop on startup in case of wrong SQL database access information, which occurs on the second table maybe due to the bad setting in DBI, please test this change
this should fix a longstanding bug where Interchange get stuck into an infinite loop on startup in case of wrong SQL database access information, which occurs on the second table maybe due to the bad setting in DBI, please test this change
A number of minor changes to Vend::Data.
* Allow a database to spring into existence without a .txt file. TO
do this, you define the field names in the NAME paramter.
Database will_be_there will_be_there.txt __SQLDSN__
Database will_be_there NAME code field1 field2
Database will_be_there CREATE_EMPTY_TXT 1
All it does is create the .txt file (or whatever the name is) from
the value of NAME array. It does take delimiters into account.
You must be just a bit careful, since if you then remove the .txt
file it will of course recreate the table. Of course you should
take that into account when setting this non-default parameter. 8-)
This will allow some one-file configurations to be added to the
system -- I guess it would be nice if you could define a default
import, too. (TODO?)
* Allow autonumber for the linked-table behavior of update_data. Before,
you couldn't autonumber because the determination of whether the data
would be set was whether the key value is present. This allows
you to set mv_data_qual=fieldname and have a non-empty value in
that field determine whether to insert or not.
* Minor cleanup, including ensuring $obj->{DELIMITER} and $obj->{delimiter}
match. I would remove one, but am too afraid of interaction with
old configs.
Remove unused variable.
Remove unused variable.
Sweeping update of Akopia/Red Hat references, to prepare for 4.8 release with current Interchange URLs and contact information.
* Add database option: DatabaseDefault HIDE_AUTO_FILES 1 Result is to hide all .sql, .*dbm, and .autonumber files by putting a "." in front of them. I got sick of having the directory listing scroll off the screen. WARNING: If this is set after databases are imported, they will be overwritten! So do it at the beginning. I don't think this one should be recommended in the documentation...
* Move most all code out of bin/interchange. The only routines that remain are: dontwarn version usage catch_warnings parse_options main_loop Once the initial startup for Interchange is done, this code is completely out of the picture. * Create new Vend::Dispatch module which contains the bulk of the code removed from bin/interchange. * Move the important update_data() subroutine to Vend::Data. * Move the session-related routines to Vend::Session. * Move the order-related routines do_order() and update_quantity() to Vend::Order. * Change many ::uneval() calls to plain uneval() or Vend::Util::uneval(). * Remove various unused tags and routines....
* Patches to make instant database handling of delimited files work. * Changed _file_security_scalar in Scan.pm to use the standard file_name_is_absolute() routine instead of homegrown check. Which exposed a rather nasty little fault in the logic there. -- If the search type is db, and the basename of the source file for the table does not match the table name, there is a big problem. The table name will be transformed by this routine, and the search will fail with a "foo non-existent table" error. I don't think this has bitten very many people, because in practice most people name the file the same as the table, but it should be corrected. Unfortunately, we don't know the search type until after this is done. My idea is that we no longer be able to find the file name for a text search based on the table name. I doubt many people were intentionally using this feature, and all you have to do is pass "products.txt" on the fi= spec to solve the problem.
* Add new "instant database", which allows you to build a database for
editing or any other use by specifying a file name.
The file name must be relative, even if NoAbsolute is not set, and
it must end in .txt or .asc. (Add .csv?)
Imported every time, of course, but only written when something
has been changed (by flagging a _Dirty bit).
[flag type=write table=Content_txt]
[data include/menus/Content.txt page 001]
[data table=include/menus/Content.txt col=page key=001 value="YES!"]
[data include/menus/Content.txt page 001]
[perl tables="Content_txt"]
my $db = $Db{Content_txt};
my $ary = $db->query('select code,page,name from Content_txt');
my $count = 0;
for(@$ary) {
push @out, uneval($_) . "\n";
$count++;
}
return join "\n", "Showed $count records in Content_txt.", @out;
[/perl]
All normal database operations seem to work.
* Fix a bug in escape_form that didn't unescape %NN parms.
these changes are made in order to get Shadow working with text databases
Add two new utility functions useful with multiple ProductFiles: product_row and product_row_hash do the same thing as product_field except they return the entire row found. (If I missed some other function that does the same thing, let me know.)
* Fix bug where wrong value was used to select $Vend::Interplate::Db key in Safe mode.
Update Andrew Wilcox's email address at his request.
Update Andrew Wilcox's email address at his request.
Big copyright date update. This will be the last time that Red Hat copyright notices get updated en masse, since the bulk of new code will very likely come from non-Red Hat employees.
initial checkin of the new Shadow database type - this is not doing anything useful yet, but I want to give a heads up on that
backported catch for missing database entry
* Fix problem with $Tag->display() called with null table, affecting "wizard" mode. * Re-introduce "restrict" tag into Interchange, unintentionally omitted when the great tag move was made. * Clean up of [sql ...] tag, which now becomes useful as a way of doing [query list=1 ...]. * Give proper encoding behavior to [display type=value ...] * Fix bad status code on PGP failure.
* Remove some debug, fix bad indentation.
Update version number and copyright year, to prepare for the eventual day when we release version 4.8.4.
* Add new MIRROR parameter for databases. This allows creation of a DBM or Memory mirror. Sequence is: 1. Table is always imported at config time. 2. Table is only imported once. 3. Text file is not required, but should be set so export can work properly and so there is a placeholder. A complete configuration is: Database products_mem products_mem.txt TAB Database products_mem MIRROR products Database products_mem MEMORY 1 MIRROR name is not set in stone yet, probably not apropos enough; suggestions are welcome. Benchmarks for 1000 separate (i.e. tag_data, no caching) accesses (repeated tries show these are representative): Doing products_mem: Class=MEMORY DSN= Data returned 247 bytes TIME=0.200 Doing products: Class=DBI DSN=dbi:mysql:test_mfound Data returned 247 bytes TIME=0.670 Doing alias_mem: Class=MEMORY DSN= Data returned 9 bytes TIME=0.180 Doing alias: Class=DBI DSN=dbi:Pg:dbname=wikicms Data returned 9 bytes TIME=0.700 Doing wiki_mem: Class=GDBM DSN= Data returned 400 bytes TIME=0.300 Doing wiki_mem2: Class=MEMORY DSN= Data returned 400 bytes TIME=0.180 Doing wiki: Class=DBI DSN=dbi:Pg:dbname=wikicms Data returned 400 bytes TIME=0.710 Gains should be even bigger as no database connections are needed on a busy system.
* Add new experimental [PREFIX-common field] that returns common
data based on code then mv_sku. Sequence is:
1. If mv_ib is set (i.e. item is ordered from a specific database)
then that is looked for first with item code.
2. Other ProductFiles are scanned in order for code match.
3. If mv_ib is set (i.e. item is ordered from a specific database)
then that is looked for with mv_sku (if existant).
4. Other ProductFiles are scanned in order for mv_sku match.
In all cases, the data is returned if it has a length.
Example:
products.txt:
sku description
os28005 Trim Brush
options.txt:
sku description
os28005-CAM-BLK Trim Brush, Camel Hair, Black
os28005-CAM-WHT
Cart:
[
{
code => 'os28005-CAM-BLK',
quantity => 1,
mv_ib => 'options',
mv_sku => 'os28005',
},
{
code => 'os28005-CAM-WHT',
quantity => 1,
mv_ib => 'options',
mv_sku => 'os28005',
},
]
[item-list]
FIELD [item-code]: [item-field description]
COMMON [item-code]: [item-common description]
[/item-list]
Yields:
FIELD os28005-CAM-BLK: Trim Brush, Camel Hair, Black
COMMON os28005-CAM-BLK: Trim Brush, Camel Hair, Black
FIELD os28005-CAM-WHT:
COMMON os28005-CAM-WHT: Trim Brush
* Add inventory check option for [item-options ...] tag. If the
item is a matrix option, the option will not be returned if
the quantity is less than 1.
Example:
[item-options inventory=inventory::quantity]
Prevent corruption of tab-delimited DB exports by filtering tabs to spaces. Unfortunately any delimiter presents these kinds of problems, but few have fairly safe default replacements like tab->space. Also make a tiny optimization around $nuke checking.
Prevent corruption of tab-delimited DB exports by filtering tabs to spaces. Unfortunately any delimiter presents these kinds of problems, but few have fairly safe default replacements like tab->space. Also make a tiny optimization around $nuke checking.
give an appropriate error message if a class couldn't be found
* Minor change to support ic:GDBM_File:directory DSN setting.... * Optional for 4.8 branch.
merged changes 2.0 vs 2.0.2.1
use a better error message than Can't call method "open_table" on an undefined value
merged changes 1.17.2.20 vs 1.17.2.21
Upping major version number after trunk/branch switch.
Move DEV_4_7_0 development branch to repository trunk.
Table/{DBI,Common}.pm, Data.pm, Config.pm:
* Add INDEX capability for SQL databases -- uses CREATE INDEX template.
* Change INDEX Database parameter to array type, adjusting routines
in Vend::Table::Common to handle for ASCII indexing.
Order.pm:
* Add handling for encryptor type "none" in pgp_encrypt.
Util.pm:
* Slightly change mime_type routine, no fuctional changes.
* Fix type in violation handler in readin()
Update copyright notices and email addresses. Standardize module headers and remove a few shebang lines.
changes to track product categories and complete order info
New dynamic variable setup encompasses three things:
1. New "DirConfig" directive that allows you to batch-set a bunch
of variables from files. The syntax:
DirConfig <directive-name> <directory-glob>
<directive-name> is usually "Variable", but could be any hash-based
directive. (No other standard directives currently make sense to set this
way.)
<directory-glob> is a filespec that could encompass multiple directories.
Files are ignored.
The directories are read for file *names* that contain only word characters,
i.e. something that would be a valid Variable. (This alone might make
it not suitable for other uses, but picking up the junk from the
in-directory-backup-file people would be intolerable.)
Then the contents of the file is used to set the variable of the
file name.
The source file name is kept in $Vend::Cfg->{DirConfig}{Variable}{VARNAME},
for use if dynamic_variables Pragma is set.
2. Pragma dynamic_variables enables dynamic updating of variables
from files...
If enabled, all @_VARIABLE_@ and __VARIABLE__ settings are checked
first to see if the source file is defined. If there is a key
present, even if its contents are blank, it is returned. Example: in
the case of this catalog.cfg entry:
DirConfig Variable templates/foundation/regions
If the file NOLEFT_TOP is present at catalog config time, __VARIABLE__ will
equal [include templates/foundation/regions/NOLEFT_TOP].
3. ...as well as database. The file takes precedence, but if
VariableDatabase is configured and there is a record existant
with the key equal to the VARIABLE name, then it will be used.
This is probably very confusing, but will be necessary for the new template
manager I am working on. I can think of quite a few other uses as well....
Very minor change, NWN. Use Vend::Cat instead of Vend::Cfg reference.
* Added Tie::ShadowHash to list of carried modules. We should add
to Bundle::Interchange, but it hasn't changed for 3 years and the
version we carry about should be OK. Using the "extra" method of
distribution.
* Cleanup of Vend::Server and scripts/interchange.PL (along with
some other modules) to move IC closer to being thread-safe for
server execution. This should make it fairly reasonable to
start testing with the PreFork mode, which is pretty
worthwhile.
WARNING: This is a dangerous change. I have messed with the state of
the global variables, and it is not at all inconceivable this will
need to be backed out as a show-stopper is found. If you are relying
on the code to any degree, I suggest you wait a while before making
this update.
Standard low traffic mode,
MaxServers 5
% /h/cgi-bin/nph-bench
Doing 1 times, pages=blank, concurrency=-n 50 -c 5.
BEGIN round 1
gfound blank: Requests per second: 5.13
mfound blank: Requests per second: 4.80
pfound blank: Requests per second: 4.80
END round 1
RPC mode
PreFork Yes
StartServers 5
MaxRequestsPerChild 100
Doing 1 2 3 times, pages=blank, concurrency=-n 50 -c 5.
BEGIN round 1
gfound blank: Requests per second: 37.94
mfound blank: Requests per second: 38.88
pfound blank: Requests per second: 35.69
END round 1
BEGIN round 2
gfound blank: Requests per second: 36.10
mfound blank: Requests per second: 37.04
pfound blank: Requests per second: 21.21
END round 2
BEGIN round 3
gfound blank: Requests per second: 27.92
mfound blank: Requests per second: 34.84
pfound blank: Requests per second: 30.92
END round 3
gfound=DBM
mfound=MySQL
pfound=PostGres
Both are serving a page without ITL in it, which essentially measures
overhead introduced by the IC server. Some of the variance in the second is
due to having to re-fork servers once reaching MaxRequestsPerChild.
Here are some times for a page which has only
<XMP>
[query list=1 sql="select * from products"][sql-code] [sql-param description] [sql-price]
[/query]
</XMP>
Without prefork:
Doing 1 times, pages=dbtest, concurrency=-n 50 -c 5.
BEGIN round 1
gfound dbtest: Requests per second: 2.54
mfound dbtest: Requests per second: 2.46
pfound dbtest: Requests per second: 1.79
With prefork:
Doing 1 times, pages=dbtest, concurrency=-n 50 -c 5.
BEGIN round 1
gfound dbtest: Requests per second: 4.23
mfound dbtest: Requests per second: 4.36
pfound dbtest: Requests per second: 2.51
END round 1
All are measured on my 800MHz Athlon with IDE. Sessions are zeroed before
each run, and a new session is created every time.
Postgres is consistently slower than MySQL and GDBM in these cases. I
did the same query using Benchmark, and it is obvious the DB takes up
much of the time.
* Fix chained_cost bug where key was improperly read as an
attribute, causing zero pricing for gift_cert in Foundation
demo.
Change second chained cost levels limit check to use new Limit directive, as requested on the mail list: http://developer.akopia.com/archive/interchange-users/2000/msg06847.html http://developer.akopia.com/archive/interchange-users/2001/msg02996.html Tested, but if there's some hidden problem I missed, please back out the change.