📄 perst.html
字号:
array element class is added to the current namespace.<LI>Unlike <b>exists</b> clause which use <code>IndexOutOfRangeError</code> exception to notify end of iteration, <b>contains with</b> will just iterate through all array elements and do not throw any exception. So performance of<b>contains with</b> is better.<LI>While it is possible to have nested <b>contains</b> clauses, <b>with</b> expression can deal with elements only ofthe one (most inner) array. </UL></OL><H3> <A NAME = "string">Strings</A></H3>All strings in JSQL have varying length and programmer should notworry about specification of maximal length for character fields. All operations acceptable for arrays are also applicable to strings. In addition to them strings have a set their own operations.First of all string can be compared with each other using standardrelation operators. At the current moment JSQL supports onlyASCII character set (corresponds to type <code>char</code> in C) andbyte-by-byte comparison of strings ignoring locality settings.<P>Construction <code>like</code> can be used for matching string with a pattern containing special wildcard characters'%' and '_'. Character '_' matches any single character, while character'%' matches any number of characters (including 0). Extended form of <code>like</code> operator with <code>escape</code> part can be used to handle characters '%' and '_' in the pattern as normal characters if they are preceded by special escape character, specified after<code>escape</code> keyword.<P> It is possible to search substring within string by <code>in</code>operator. Expression <code>('blue' in color)</code> will be truefor all records which <code>color</code> fields contains 'blue' word. Strings can be concatenated by <code>+</code> or <code>||</code> operators.Last one was added only for compatibility with ANSI SQL standard.As far as JSQL doesn't support implicit conversion to string type in expressions, semantic of operator <code>+</code> can be redefined forstrings.<P><H3> <A NAME = "reference">References</A></H3>References can be dereferenced using the same dot notation as used foraccessing structure components. For example the following query<PRE> company.address.city = 'Chicago'</PRE>will access record referenced by <code>company</code> component of<code>Contract</code> record and extract city component of<code>address</code> field of referenced record from <code>Supplier</code>table.<P>References can be checked for <code>null</code> by <code>is null</code>or <code>is not null</code> predicates. Also references can be compared for equality with each other as well as with special <code>null</code>keyword. When null reference is dereferenced, exception is be raisedby JSQL.<P>There is special keyword <code>current</code>, which can be used to getreference to current record during table search. Usually <code>current</code>keyword is used for comparison of current record identifier withother references or locating it within array of references. For example, the following query will search in <code>Contract</code> table for all active contracts(assuming that field <code>canceledContracts</code> has <code>Contract[]</code> type): <PRE> current not in supplier.canceledContracts</PRE><P>Programmer can define methods for structures, which can be usedin queries with the same syntax as normal structure components. Such methods should have no arguments except pointer to the object to whichthey belong (<code>this</code> pointer in C#), and should returnatomic value (of boolean, numeric, string or reference type).Also method should not change object instance (immutable method).So user-defined methods can be used for creation <I>virtual</I> components - components which are not stored in database, but instead if this are calculatedusing values of other components. For example, you can use standard .Net<code>DateTime</code> class with such propertiesas <code>Year</code>, <code>Month</code>...So it is possible to specify queries like: "<code>delivery.Year = 99</code>"in application, where <code>delivery</code> record field has <code>DateTime</code> type.<P><H3> <A NAME = "function">Functions</A></H3><TABLE BORDER ALIGN="center"><CAPTION>Predefined functions</CAPTION><TR><TH>Name</TH><TH>Argument type</TH><TH>Return type</TH><TH>Description</TH></TR><TR><TD>abs</TD><TD>integer</TD><TD>integer</TD><TD>absolute value of the argument</TD></TR><TR><TD>abs</TD><TD>real</TD><TD>real</TD><TD>absolute value of the argument</TD></TR><TR><TD>sin</TD><TD>real</TD><TD>real</TD><TD>sin (rad)</TD></TR><TR><TD>cos</TD><TD>real</TD><TD>real</TD><TD>cos (rad)</TD></TR><TR><TD>tan</TD><TD>real</TD><TD>real</TD><TD>tan (rad)</TD></TR><TR><TD>asin</TD><TD>real</TD><TD>real</TD><TD>arcsin</TD></TR><TR><TD>acos</TD><TD>real</TD><TD>real</TD><TD>arccos</TD></TR><TR><TD>atan</TD><TD>real</TD><TD>real</TD><TD>arctan</TD></TR><TR><TD>exp</TD><TD>real</TD><TD>real</TD><TD>exponent</TD></TR><TR><TD>log</TD><TD>real</TD><TD>real</TD><TD>natural logarithm</TD></TR><TR><TD>ceil</TD><TD>real</TD><TD>real</TD><TD>the smallest integer value that is not less than the argument</TD></TR><TR><TD>floor</TD><TD>real</TD><TD>real</TD><TD>the largest integer value that is not greater than the argument</TD></TR><TR><TD>integer</TD><TD>real</TD><TD>integer</TD><TD>conversion of real to integer</TD></TR><TR><TD>length</TD><TD>array</TD><TD>integer</TD><TD>number of elements in array</TD></TR><TR><TD>lower</TD><TD>string</TD><TD>string</TD><TD>lowercase string</TD></TR><TR><TD>real</TD><TD>integer</TD><TD>real</TD><TD>conversion of integer to real</TD></TR><TR><TD>string</TD><TD>integer</TD><TD>string</TD><TD>conversion of integer to string</TD></TR><TR><TD>string</TD><TD>real</TD><TD>string</TD><TD>conversion of real to string</TD></TR><TR><TD>upper</TD><TD>string</TD><TD>string</TD><TD>uppercase string</TD></TR></TABLE><P><H3> <A NAME = "optimization">Optimization</A></H3>JSQL provides mechanism for fast location of object by unique primary key.When query condition is check for equality of scalar (numeric or string) fieldand constant value or query condition is conjunction (logical AND) of operands and left operand is check for equality of scalar field and constant value then JSQL tries to apply index to locate object by this key value.If object was found but query condition is is conjunction, then JSQL also checks that value of right operand is true.<P>To be able to use indices, programmer has obtain Query object and register indices in it.JSQL supports Perst <code>Index</code> and <code>FieldIndex</code> indices.Indices are located by JSQL by field name. It is assumed that class objects objectsreturned by index iterator is the same as specified in <code>select</code> query. If you are going to use the same Query instance for selecting data from different collections(with different collection member class), please check that there no name conflict for key fields, i.e. index corresponding one collection will not be applied for another collection.<P>Maintaining indices is responsibility of programmer. JSQL is only using indices for searching element by key.<P><H3> <A NAME = "database">Database</A></H3>For those you prefer to deal with records in tables instead of objects,Perst provides <code>Database</code> class. This class emulates relational database on top of Perst. Certainly even with thisclass, Perst provides very object-orient way of dealing with persistent data.<code>Database</code> class allows you to create/drop table, add/drop indices, create/update/delete records. It automatically update indices when new record is added or removed.Also <code>Database</code> class makes it possible to prepare and execute queries.<P><code>Database</code> class is used as wrapper for underlying Perst storage. Storagepassed to the constructor of <code>Database</code> class should be opened and either not initialized, either initialized before by the same <code>Database</code> constructor. It is not possibleto attach database to Perst Storage with existed root object other than one setby <code>Database</code> constructor.<P>A table in database are associated with C# class. Almost all methodsof database class requires passing of <code>Class</code> parameteror persistent object instance. In last case class of this object is used.If Perst founds no table associated with the class, it tries to find table for superclass and so on... So it is possible to have "polymorphic" table - table containing records (object) of multiple classes derivedfrom this one. Methods dealing with object instance have overloaded versionwhere class can be specified explicitly. It makes it possible to place objectin table associated with some particular interface.<P>Database provides two ways of querying tables: using simple and prepared queries.In first case <code>Database.select</code> directly returns result of query execution(iterator). In second case it is possible to execute prepared query multiple times,specifying different values of parameters.<P>Please find more information of Database methods in API documentation and look at JsqlSSD example - <i>Supplier-Shipment-Detail</i> databasebuilt using Database class.<P> <H2> <A NAME = "transparent">Transparent API's</A></H2><H3> <A NAME = "remoting">Using .Net remoting API</A></H3>.Net framework provides System.Runtime.Remoting package for easyimplementation of distributed applications. Programmer should only derivedits class from ContextBoundObject and use ContextAttribute which is responsiblefor providing <i>message sink</i>: mechanism for controlling invocation of methods and accessto fields of the object. Using this API its is possible to implement not only distributedsystem, but also any system based on <i>metaobject protocol</i>: protocol of controllingbehavior of the object. For example it is possible to implement transparent interface to objectoriented database using this API.<p>Perst.NET includes two classes PersistentContext and TransparentPersistenceAttrributewhich are used to provide transparent persistence for C# objects using .Net remoting API. If application class is derived from PersistentContext and marked with TransparentPersistence attribute, it will automatically load on demand its content from the database and automatically store content if the object is modified. Implementation of <code>recursiveLoading</code> method in <code>PersistentContext</code> class returns false, so object are loaded from the database only when them are accessed.<P>But there are two significant restrictions on using remoting API:<UL><LI>Remoting API can handle only public members of the class<LI>It cause significant performance overhead (invocation of method through remoting APIis about 100 times slower than normal method invocation).</UL><P><code>TransparentGuess</code> example illustrates using of this Perst transparent API.<p><H3><A NAME = "props">Using virtual properties</A></H3>Yet another attempt to build transparent API to Perst without using specialpreprocessor (enhancer) is based on the idea of using virtual properties.Unlike Java, C# provides property mechanism which allows to encapsulate representation of object component. Idea originally proposed by <A href="shiziye@hotmail.com">Shi Ziye</A> is very simple - generate wrapper classwhich will implement these properties. So programmer should not worry any moreabout cutting recursive loading of objects by redefinition of<code>IPersistent.RecursiveLoading</code> method and explicit loading of object using <code>IPersistent.Load</code> method or about explicitmarking of updated object by <code>IPersistent.Modify</code> method.So a lot of error prone things are disappears. But certainly this approach has their own drawbacks:<OL><LI>Your persistent objects can not have persistent fields, instead of ityou should define abstract properties (it is also possible to define propertiesin interface). Fortunately C# provides convenient mechanism for workingwith properties, so it will significantly complicates programming. <LI>You can not create persistent object by new operator - you shoulduse <code>IStorage.CreateClass</code> method which will generate wrapper classand create instance of this class. Also persistent class should have no constructorexcept default. And this default constructor should not do something else except initialization of transient components, because this constructor will be invoked each time object is loaded from the storage.<LI>It is not possible to have arrays of references. You have to use <code>Perst.PArray</code> class instead.<LI>Generation of wrapper classes is not cheap operations, so if there are many classesin your applications, then it can take significant time during database open.<LI>This mechanism will not work in Compact.Net framework because it doesn't support code generation at runtime.</OL><P>There are two possible ways of defining persistent classes using this API.First is based in using interfaces:<pre>class Node:IPersistent { int Weight { get; set; } Node Parent { get; set; }}</pre>Please notice that you should extend IPersistent interface.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -