Wierdness with mvopen

2 views
Skip to first unread message

virtualkiwi

unread,
May 3, 2007, 9:09:32 PM5/3/07
to miva-script
I've run into some inexplicable wierdness using mvopen with Xbase
files.

I have tried two ways of opening the table:

<mvdo file="{g.lib:db}" name="l.indexes"
value="{order_by(l.table,'ORDER')}">
<mvassign name="g.tables:dbTemplateItems:open" value="1">
<mvopen name="dbTemplateItems" database="{g.strDataRoot $
'tempitem.dbf'}" indexes="{l.indexes}">

(The order_by() function goes away and builds a string with the
correct paths given the table alias, and the fields that are indexed.)

The second (preferred) method also works without errors::

<mvdo file="{g.lib:db}" name="l.ok"
value="{open_table(l.table,'ORDER')}">

(which corresponds to the following function. Note: the order_by()
function called in this function is exactly the same as in the first
example, but doesn't have to mvdo, as it's in the same file.)

<mvfunction name="open_table" parameters="alias, order"
standardoutputlevel="">
<MvCOMMENT>
# Function to check whether a table is open, and if not, open it
# This looks like a long winded way to open a table, but provides
# some error checking, and simple indexing.
# Alias is the alias of the table in the Tables db
# order is a comma delimited list of index fields used to
sort the table
#
</MvCOMMENT>
<mvopen name="dbTables" database="{g.strDataRoot $ 'tables.dbf'}"
indexes="{g.strDataRoot $ 'Xtab2.mvx'}">
<mvfind name="dbTables" value="{l.alias}" exact="EXACT">
<mvassign name="g.tables:dbTables:open" value="1">
<MvIF EXPR="{dbTables.d.alias EQ l.alias}">
<MvCOMMENT>
# Don't want to open table if it is already open, however might want
to change index.
</MvCOMMENT>
<MvIF EXPR="{NOT miva_variable_value('g.tables:' $ l.alias $
':open')}">
<mvassign name="l.strPath" value="{get_path(l.alias)}">
<mvassign name="l.strIndexes" value="{order_by(l.alias,
l.order)}">
<MvCOMMENT>
# Check to see if the selected field is indexed. If not, open
table unindexed
</MvCOMMENT>
<MvIF EXPR="{l.strIndexes}">
<mvopen name="{l.alias}" database="{l.strPath $ dbTables.d.file}"
indexes="{l.strIndexes}">
<mvelse>
<mvopen name="{l.alias}" database="{l.strPath $
dbTables.d.file}">
</MvIF>
<MvCOMMENT>
# Now that the table is open, set a flag to prevent it being
opened again
</MvCOMMENT>
<mvassign name="{'g.tables:' $ l.alias $ ':open'}" value="1">
<mvassign name="g.tables:dbTables:open" value="">
<MvCLOSE NAME="dbTables">
<mvfuncreturn value="1">
<mvelse>
<MvCOMMENT>
# If the table is already open, then just want to change the
indexes
</MvCOMMENT>
<MvEVAL EXPR="{'Table open'}">
<MvSETINDEX NAME="{l.alias}" INDEXES="{order_by(l.alias,
l.order)}">
</MvIF>
<mvelse>
<MvEVAL EXPR="{'Table not found'}"><mvexit>
</mvif>
<mvassign name="g.tables:dbTables:open" value="">
<MvCLOSE NAME="dbTables">
<mvfuncreturn value="1">
</mvfunction>

But:

When I try to run the following code immediately after the table
opening code, the mvwhile loop does not return anything in the second
case, but works fine in the first case.

<mvfilter name="{l.table}" filter="{dbTemplateItems.d.template EQ
l.strTemplate}">
<mvskip name="{l.table}">
<MvWHILE EXPR="{NOT dbTemplateItems.d.eof}">
<mvassign name="l.form:content" index="{l.intCount}"
value="{dbTemplateItems.d.content}">
<mvassign name="l.form:type" index="{l.intCount}"
value="{dbTemplateItems.d.type}">
<mvassign name="l.intCount" value="{l.intCount + 1}">
<mvskip name="{l.table}">
</MvWHILE>

The table is open, ie I can mvskip and mvgo without error, and I can
prove that the table is open by trying to to a manual mvopen of the
same file which will spit out an error saying the database is already
open.

Any idea what is going on here?

Richard Grevers

unread,
May 3, 2007, 11:59:52 PM5/3/07
to miva-...@googlegroups.com
On 5/4/07, virtualkiwi <virtu...@gmail.com> wrote:
>
> I've run into some inexplicable wierdness using mvopen with Xbase
> files.
<snip>

>
> When I try to run the following code immediately after the table
> opening code, the mvwhile loop does not return anything in the second
> case, but works fine in the first case.
>
> <mvfilter name="{l.table}" filter="{dbTemplateItems.d.template EQ
> l.strTemplate}">
> <mvskip name="{l.table}">
> <MvWHILE EXPR="{NOT dbTemplateItems.d.eof}">
> <mvassign name="l.form:content" index="{l.intCount}"
> value="{dbTemplateItems.d.content}">
> <mvassign name="l.form:type" index="{l.intCount}"
> value="{dbTemplateItems.d.type}">
> <mvassign name="l.intCount" value="{l.intCount + 1}">
> <mvskip name="{l.table}">
> </MvWHILE>
>
> The table is open, ie I can mvskip and mvgo without error, and I can
> prove that the table is open by trying to to a manual mvopen of the
> same file which will spit out an error saying the database is already
> open.
>
> Any idea what is going on here?
>
At a rough guess its because the initial <MvSKIP> is putting you past
eof for the filter. I notice that your filter uses a local variable.
Do your two methods have differently structured functions such that
l.strTemplate is undefined in one of them?

On a general note, if you can design around using Filters on indexed
databases, do so and you will get considerable efficiency gains.

--
Richard Grevers, New Plymouth, New Zealand
Hat 1: Development Engineer, Webfarm Ltd.
Hat 2: Dramatic Design www.dramatic.co.nz
Lost yet? http://www.lost.eu/3d33f

virtu...@gmail.com

unread,
May 4, 2007, 3:47:55 AM5/4/07
to miva-...@googlegroups.com


2007/5/4, Richard Grevers <richard...@gmail.com>:
Oops! The <mvskip> got left in there from trying to figure out what was causing the problem, but it doesn't make any difference.

l.strTemplate is a parameter that is passed to the function that uses either of the two methods to open the database.
I tried assigning it to a global variable inside the function AFTER the <mvdo> and BINGO! It worked.
That still doesn't make sense to me, as the global is defined after the call to open the database, while if I use the local variable in the filter expression, it doesn't work, in the second case, even though the local variable was already defined in the function where the filter is applied.

Yes, I'm aware of potential efficiency gains not using filters or indexes, but I'm working on a kind of database abstraction layer both to make my code more readable and manageable, and also to make it easier to scale to a mySQL or ODBC backend, without having to add heaps of additional code into each module.
 
Reply all
Reply to author
Forward
0 new messages