Merged revisions 11971-11975,11978,11980,11982,11984 via svnmerge from
authorphasefx <phasefx@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 26 Jan 2009 22:38:17 +0000 (22:38 +0000)
committerphasefx <phasefx@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 26 Jan 2009 22:38:17 +0000 (22:38 +0000)
svn://svn.open-ils.org/ILS/trunk

........
  r11971 | scottmk | 2009-01-26 08:55:54 -0500 (Mon, 26 Jan 2009) | 10 lines

  1. Gave more descriptive names to a number of variables,
  sometimes introducing additional names instead of reusing
  existing names for multiple unrelated purposes.

  2. Rewrote some of the permacrud-related code to
  improve clarity.

  3. Tweaked some debugging messages so that we wouldn't
  try to format them with NULL pointers.
........
  r11972 | erickson | 2009-01-26 12:10:10 -0500 (Mon, 26 Jan 2009) | 1 line

  enable direct use of xact_begin/rollback/commit for managing transactions.  change xact_start to xact_begin for consistency
........
  r11973 | erickson | 2009-01-26 12:20:39 -0500 (Mon, 26 Jan 2009) | 1 line

  added savepoint support
........
  r11974 | erickson | 2009-01-26 13:50:59 -0500 (Mon, 26 Jan 2009) | 1 line

  added support for returning the metarecord holds in open-ils.circ.holds.retrieve_all_from_title
........
  r11975 | erickson | 2009-01-26 14:04:51 -0500 (Mon, 26 Jan 2009) | 1 line

  we've seen sip clients in the field that do not handle unicode very well.  until we track down the problem, strip the 'wide characters' from the title string
........
  r11978 | phasefx | 2009-01-26 14:47:30 -0500 (Mon, 26 Jan 2009) | 1 line

  accomodate metarecord holds from open-ils.circ.holds.retrieve_all_from_title.  Thanks Bill!
........
  r11980 | dbs | 2009-01-26 15:01:05 -0500 (Mon, 26 Jan 2009) | 5 lines

  Forward port r11979 from rel_1_4:
  Use local log files rather than syslog by default.
  Set default loglevel to 3 (Info) to avoid filling disk space of unsuspecting users.
  Use LOCALSTATEDIR to enable configure to set location of local log files.
........
  r11982 | erickson | 2009-01-26 15:43:27 -0500 (Mon, 26 Jan 2009) | 1 line

  added a streaming, batch mvr retrieval method
........
  r11984 | scottmk | 2009-01-26 15:56:33 -0500 (Mon, 26 Jan 2009) | 14 lines

  Eliminated all calls to oilsIDLFindPath() in this file.

  This change eliminates the overhead of parsing path
  strings, including the malloc and free that such
  parsing entails.

  In addition: in most cases we had been calling
  oilsIDLFindPath() twice, once to verify that the class
  existed, and again to find whatever piece of it we
  wanted.  This duplication of effort is now gone.
  -This line, and those below, will be ignored--

  M    Open-ILS/src/c-apps/oils_idl-core.c
........

git-svn-id: svn://svn.open-ils.org/ILS/branches/staff-client-experiment@11986 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/opensrf_core.xml.example
Open-ILS/src/c-apps/oils_idl-core.c
Open-ILS/src/perlmods/OpenILS/Application/Circ/Holds.pm
Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm
Open-ILS/src/perlmods/OpenILS/SIP/Item.pm
Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm
Open-ILS/xul/staff_client/server/patron/holds.js

index d474210..9b9ecd9 100644 (file)
-<?xml version='1.0'?>
+<?xml version="1.0"?>
+<!-- 
+Example OpenSRF bootstrap configuration file for Evergreen
+-->
 <config>
+  <!-- Options for <loglevel>: 0 None, 1 Error, 2 Warning, 3 Info, 4 debug -->
+  <opensrf>
+    <routers>
 
-    <!-- Options for <loglevel>: 0 None, 1 Error, 2 Warning, 3 Info, 4 debug -->
-
-    <opensrf>
-
-        <routers>
-            <!-- define the list of routers our services will register with -->
-            <router>
-                <!-- This is the public router.  On this router, we only register applications
-                     which should be accessible to everyone on the opensrf network -->
-                <name>router</name>
-                <domain>public.localhost</domain>
-                <services>
-                    <service>opensrf.math</service> 
-                    <service>open-ils.cat</service> 
-                    <service>open-ils.supercat</service> 
-                    <service>open-ils.search</service> 
-                    <service>open-ils.circ</service> 
-                    <service>open-ils.actor</service> 
-                    <service>open-ils.auth</service> 
-                    <service>open-ils.fielder</service> 
-                    <service>open-ils.collections</service>  
-                    <service>open-ils.reporter</service>  
-                </services>
-            </router>
-
-            <router>
-                <!-- This is the private router.  All applications must register with 
-                    this router, so no explicit <services> section is required -->
-                <name>router</name>
-                <domain>private.localhost</domain>
-            </router>
-        </routers>
-
-        <!-- Our domain should match that of the private router -->
-        <domain>private.localhost</domain>
-        <username>osrf</username>
-        <passwd>osrf</passwd>
-        <port>5222</port>
-
-        <!-- name of the router used on our private domain.  
-        this should match one of the <name> of the private router above -->
-        <router_name>router</router_name>
-
-        <logfile>/openils/var/log/osrfsys.log</logfile>
-        <!--
-        <logfile>syslog</logfile>
-        <syslog>local0</syslog>
-        <actlog>local1</actlog>
+      <!-- define the list of routers our services will register with -->
+      <router>
+        <!-- 
+          This is the public router.  On this router, we only register
+          applications which should be accessible to everyone on the OpenSRF
+          network
         -->
-        <loglevel>3</loglevel>
-        <settings_config>/openils/conf/opensrf.xml</settings_config>
-    </opensrf>
-
-
-    <!-- The section between <gateway>...</gateway> is a standard OpenSRF C stack config file -->
-    <gateway>
-
-        <client>true</client>
-        <router_name>router</router_name>
-
-        <!-- The gateway connects to the public domain for security -->
+        <name>router</name>
         <domain>public.localhost</domain>
 
-      <!-- this section will be soon deprecated for multi-domain mode... -->
-      <services>
-         <service>opensrf.math</service>
-         <service>opensrf.dbmath</service>
-         <service>open-ils.cat</service>
-         <service>open-ils.search</service>
-         <service>open-ils.circ</service>
-         <service>open-ils.actor</service>
-         <service>open-ils.auth</service>
-         <service>open-ils.collections</service>
-         <service>open-ils.reporter</service>
-      </services>
-
-        <!-- jabber login info -->
-        <username>osrf</username>
-        <passwd>osrf</passwd>
-        <port>5222</port>
-        <loglevel>3</loglevel>
-        <logfile>/openils/var/log/gateway.log</logfile>
+        <services>
+          <service>opensrf.math</service>
+          <service>open-ils.cat</service>
+          <service>open-ils.supercat</service>
+          <service>open-ils.search</service>
+          <service>open-ils.circ</service>
+          <service>open-ils.actor</service>
+          <service>open-ils.auth</service>
+          <service>open-ils.fielder</service>
+          <service>open-ils.collections</service>
+          <service>open-ils.reporter</service>
+        </services>
+      </router>
+
+      <router>
         <!--
-        <logfile>syslog</logfile>
-        <syslog>local6</syslog>
-        <actlog>local1</actlog>
+          This is the private router.  All applications must register with 
+          this router, so no explicit <services> section is required
         -->
-    </gateway>
-
-    <!-- ======================================================================================== -->
-
-    <routers>
-        <router> <!-- public router -->
-            <trusted_domains>
-                <!-- allow private services to register with this router 
-                     and public client to send requests to this router. -->
-                <server>private.localhost</server>
-                <!-- also allow private clients to send to the router so it can receive error messages -->
-                <client>private.localhost</client>
-                <client>public.localhost</client>
-            </trusted_domains>
-            <transport>
-                <server>public.localhost</server>
-                <port>5222</port>
-                <unixpath>/openils/var/sock/unix_sock</unixpath>
-                <username>router</username>
-                <password>osrf</password>
-                <resource>router</resource>
-                <connect_timeout>10</connect_timeout>
-                <max_reconnect_attempts>5</max_reconnect_attempts>
-            </transport>
-            <logfile>syslog</logfile>
-            <syslog>local2</syslog>
-            <loglevel>5</loglevel>
-        </router>
-        <router> <!-- private router -->
-            <trusted_domains>
-                <server>private.localhost</server>
-                <!-- only clients on the private domain can send requests to this router -->
-                <client>private.localhost</client>
-            </trusted_domains>
-            <transport>
-                <server>private.localhost</server>
-                <port>5222</port>
-                <username>router</username>
-                <password>osrf</password>
-                <resource>router</resource>
-                <connect_timeout>10</connect_timeout>
-                <max_reconnect_attempts>5</max_reconnect_attempts>
-            </transport>
-            <logfile>syslog</logfile>
-            <syslog>local2</syslog>
-            <loglevel>4</loglevel>
-        </router>
+        <name>router</name>
+        <domain>private.localhost</domain>
+      </router>
     </routers>
 
-    <!-- ======================================================================================== -->
-
-</config>
-
-
+    <!-- Our domain should match that of the private router -->
+    <domain>private.localhost</domain>
+    <username>osrf</username>
+    <passwd>osrf</passwd>
+    <port>5222</port>
+
+    <!-- 
+      Name of the router used on our private domain.  
+      This should match one of the <name> of the private router above.
+     -->
+    <router_name>router</router_name>
+
+    <logfile>LOCALSTATEDIR/log/osrfsys.log</logfile>
+    <!--
+      <logfile>syslog</logfile>
+      <syslog>local0</syslog>
+      <actlog>local1</actlog>
+     -->
+    <loglevel>3</loglevel>
+    <settings_config>SYSCONFDIR/opensrf.xml</settings_config>
+  </opensrf>
+  <!-- 
+    The section between <gateway>...</gateway> is a standard OpenSRF C
+    stack configuration file
+  -->
+  <gateway>
+    <client>true</client>
+    <router_name>router</router_name>
+
+    <!-- The gateway connects to the public domain for security -->
+    <domain>public.localhost</domain>
+
+    <!-- This section will be soon deprecated for multi-domain mode... -->
+    <services>
+      <service>opensrf.math</service>
+      <service>opensrf.dbmath</service>
+      <service>open-ils.cat</service>
+      <service>open-ils.search</service>
+      <service>open-ils.circ</service>
+      <service>open-ils.actor</service>
+      <service>open-ils.auth</service>
+      <service>open-ils.collections</service>
+      <service>open-ils.reporter</service>
+    </services>
+
+    <!-- jabber login info -->
+    <username>osrf</username>
+    <passwd>osrf</passwd>
+    <port>5222</port>
+    <loglevel>3</loglevel>
+    <logfile>LOCALSTATEDIR/log/gateway.log</logfile>
+    <!--
+      <logfile>syslog</logfile>
+      <syslog>local6</syslog>
+      <actlog>local1</actlog>
+    -->
+  </gateway>
+  <!-- ======================================================================================== -->
+  <routers>
+    <router>
+      <!-- public router -->
+      <trusted_domains>
+        <!-- 
+          Allow private services to register with this router 
+          and public client to send requests to this router. 
+        -->
+        <server>private.localhost</server>
 
+        <!-- 
+          Also allow private clients to send to the router so it
+          can receive error messages
+        -->
+        <client>private.localhost</client>
+        <client>public.localhost</client>
 
+      </trusted_domains>
+      <transport>
+        <server>public.localhost</server>
+        <port>5222</port>
+        <unixpath>LOCALSTATEDIR/sock/unix_sock</unixpath>
+        <username>router</username>
+        <password>osrf</password>
+        <resource>router</resource>
+        <connect_timeout>10</connect_timeout>
+        <max_reconnect_attempts>5</max_reconnect_attempts>
+      </transport>
+      <logfile>LOCALSTATEDIR/log/router-public.log</logfile>
+      <!--
+        <logfile>syslog</logfile>
+        <syslog>local2</syslog>
+      -->
+      <loglevel>3</loglevel>
+    </router>
+    <router>
+      <!-- private router -->
+      <trusted_domains>
+        <server>private.localhost</server>
+        <!-- 
+          Only clients on the private domain can send requests to this router
+         -->
+        <client>private.localhost</client>
+      </trusted_domains>
+      <transport>
+        <server>private.localhost</server>
+        <port>5222</port>
+        <username>router</username>
+        <password>osrf</password>
+        <resource>router</resource>
+        <connect_timeout>10</connect_timeout>
+        <max_reconnect_attempts>5</max_reconnect_attempts>
+      </transport>
+      <logfile>LOCALSTATEDIR/log/router-private.log</logfile>
+      <!--
+        <logfile>syslog</logfile>
+        <syslog>local2</syslog>
+      -->
+      <loglevel>3</loglevel>
+    </router>
+  </routers>
+  <!-- ======================================================================================== -->
+</config>
index 9864239..19240d3 100644 (file)
@@ -28,10 +28,10 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
 
        if (idlHash) return idlHash;
 
-       char* string_tmp = NULL;
+       char* prop_str = NULL;
 
        idlHash = osrfNewHash();
-       osrfHash* usrData = NULL;
+       osrfHash* class_def_hash = NULL;
 
        osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
        idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
@@ -48,46 +48,45 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
        while (kid) {
                if (!strcmp( (char*)kid->name, "class" )) {
 
-                       usrData = osrfNewHash();
-                       osrfHashSet( usrData, xmlGetProp(kid, BAD_CAST "id"), "classname");
-                       osrfHashSet( usrData, xmlGetNsProp(kid, BAD_CAST "fieldmapper", BAD_CAST OBJECT_NS), "fieldmapper");
-                       osrfHashSet( usrData, xmlGetNsProp(kid, BAD_CAST "readonly", BAD_CAST PERSIST_NS), "readonly");
+                       class_def_hash = osrfNewHash();
+                       char* current_class_name = (char*) xmlGetProp(kid, BAD_CAST "id");
+                       
+                       osrfHashSet( class_def_hash, current_class_name, "classname" );
+                       osrfHashSet( class_def_hash, xmlGetNsProp(kid, BAD_CAST "fieldmapper", BAD_CAST OBJECT_NS), "fieldmapper" );
+                       osrfHashSet( class_def_hash, xmlGetNsProp(kid, BAD_CAST "readonly", BAD_CAST PERSIST_NS), "readonly" );
 
-                       osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
+                       osrfHashSet( idlHash, class_def_hash, current_class_name );
 
-                       string_tmp = NULL;
-                       if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "tablename", BAD_CAST PERSIST_NS))) {
-                               osrfLogDebug(OSRF_LOG_MARK, "Using table '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+                       if ((prop_str = (char*)xmlGetNsProp(kid, BAD_CAST "tablename", BAD_CAST PERSIST_NS))) {
+                               osrfLogDebug(OSRF_LOG_MARK, "Using table '%s' for class %s", prop_str, current_class_name );
                                osrfHashSet(
-                                       usrData,
-                                       strdup( string_tmp ),
+                                       class_def_hash,
+                                       strdup( prop_str ),
                                        "tablename"
                                );
                        }
 
-                       string_tmp = NULL;
-                       if ((string_tmp = (char*)xmlGetNsProp(kid, BAD_CAST "virtual", BAD_CAST PERSIST_NS))) {
+                       if ((prop_str = (char*)xmlGetNsProp(kid, BAD_CAST "virtual", BAD_CAST PERSIST_NS))) {
                                osrfHashSet(
-                                       usrData,
-                                       strdup( string_tmp ),
+                                       class_def_hash,
+                                       strdup( prop_str ),
                                        "virtual"
                                );
                        }
 
                        // Tokenize controller attribute into an osrfStringArray
-                       string_tmp = (char*) xmlGetProp(kid, BAD_CAST "controller");
-                       if( string_tmp )
-                               osrfLogDebug(OSRF_LOG_MARK, "Controller list is %s", string_tmp );
-                       osrfStringArray* controller = osrfStringArrayTokenize( string_tmp, ' ' );
-                       osrfHashSet( usrData, controller, "controller");
-
-                       osrfHash* _tmp;
-                       osrfHash* links = osrfNewHash();
-                       osrfHash* fields = osrfNewHash();
+                       prop_str = (char*) xmlGetProp(kid, BAD_CAST "controller");
+                       if( prop_str )
+                               osrfLogDebug(OSRF_LOG_MARK, "Controller list is %s", prop_str );
+                       osrfStringArray* controller = osrfStringArrayTokenize( prop_str, ' ' );
+                       osrfHashSet( class_def_hash, controller, "controller");
+
+                       osrfHash* current_links_hash = osrfNewHash();
+                       osrfHash* current_fields_hash = osrfNewHash();
                        osrfHash* pcrud = osrfNewHash();
 
-                       osrfHashSet( usrData, fields, "fields" );
-                       osrfHashSet( usrData, links, "links" );
+                       osrfHashSet( class_def_hash, current_fields_hash, "fields" );
+                       osrfHashSet( class_def_hash, current_links_hash, "links" );
 
                        xmlNodePtr _cur = kid->children;
 
@@ -95,20 +94,18 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
 
                                if (!strcmp( (char*)_cur->name, "fields" )) {
 
-                                       string_tmp = NULL;
-                                       if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
+                                       if( (prop_str = (char*)xmlGetNsProp(_cur, BAD_CAST "primary", BAD_CAST PERSIST_NS)) ) {
                                                osrfHashSet(
-                                                       usrData,
-                                                       strdup( string_tmp ),
+                                                       class_def_hash,
+                                                       strdup( prop_str ),
                                                        "primarykey"
                                                );
                                        }
 
-                                       string_tmp = NULL;
-                                       if( (string_tmp = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
+                                       if( (prop_str = (char*)xmlGetNsProp(_cur, BAD_CAST "sequence", BAD_CAST PERSIST_NS)) ) {
                                                osrfHashSet(
-                                                       usrData,
-                                                       strdup( string_tmp ),
+                                                       class_def_hash,
+                                                       strdup( prop_str ),
                                                        "sequence"
                                                );
                                        }
@@ -121,59 +118,56 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
                                                        continue;
                                                }
 
-                                               _tmp = osrfNewHash();
+                                               osrfHash* field_def_hash = osrfNewHash();
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
+                                               if( (prop_str = (char*)xmlGetNsProp(_f, BAD_CAST "array_position", BAD_CAST OBJECT_NS)) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               field_def_hash,
+                                                               strdup( prop_str ),
                                                                "array_position"
                                                        );
                                                }
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "i18n", BAD_CAST PERSIST_NS)) ) {
+                                               if( (prop_str = (char*)xmlGetNsProp(_f, BAD_CAST "i18n", BAD_CAST PERSIST_NS)) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               field_def_hash,
+                                                               strdup( prop_str ),
                                                                "i18n"
                                                        );
                                                }
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
+                                               if( (prop_str = (char*)xmlGetNsProp(_f, BAD_CAST "virtual", BAD_CAST PERSIST_NS)) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               field_def_hash,
+                                                               strdup( prop_str ),
                                                                "virtual"
                                                        );
                                                }
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
+                                               if( (prop_str = (char*)xmlGetNsProp(_f, BAD_CAST "primitive", BAD_CAST PERSIST_NS)) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               field_def_hash,
+                                                               strdup( prop_str ),
                                                                "primitive"
                                                        );
                                                }
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
+                                               if( (prop_str = (char*)xmlGetProp(_f, BAD_CAST "name")) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               field_def_hash,
+                                                               strdup( prop_str ),
                                                                "name"
                                                        );
-                                               }
-
-                                               osrfLogDebug(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+                                                       osrfLogDebug(OSRF_LOG_MARK, 
+                                                               "Found field %s for class %s", prop_str, current_class_name );
+                                               } else
+                                                       osrfLogDebug(OSRF_LOG_MARK, 
+                                                               "Found field with no name for class %s", current_class_name );
 
                                                osrfHashSet(
-                                                       fields,
-                                                       _tmp,
-                                                       strdup( string_tmp )
+                                                       current_fields_hash,
+                                                       field_def_hash,
+                                                       prop_str
                                                );
                                                _f = _f->next;
                                        }
@@ -188,62 +182,61 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
                                                        continue;
                                                }
 
-                                               _tmp = osrfNewHash();
+                                               osrfHash* link_def_hash = osrfNewHash();
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
+                                               if( (prop_str = (char*)xmlGetProp(_l, BAD_CAST "reltype")) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               link_def_hash,
+                                                               strdup( prop_str ),
                                                                "reltype"
                                                        );
-                                               }
-                                               osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Adding link with reltype %s", prop_str );
+                                               } else
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Adding link with no reltype" );
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
+                                               if( (prop_str = (char*)xmlGetProp(_l, BAD_CAST "key")) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               link_def_hash,
+                                                               strdup( prop_str ),
                                                                "key"
                                                        );
-                                               }
-                                               osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link fkey is %s", prop_str );
+                                               } else
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link with no fkey" );
 
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
+                                               if( (prop_str = (char*)xmlGetProp(_l, BAD_CAST "class")) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               link_def_hash,
+                                                               strdup( prop_str ),
                                                                "class"
                                                        );
-                                               }
-                                               osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", prop_str );
+                                               } else
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link with no fclass" );
 
                                                // Tokenize map attribute into an osrfStringArray
-                                               string_tmp = (char*) xmlGetProp(_l, BAD_CAST "map");
-                                               if( string_tmp )
-                                                       osrfLogDebug(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
-                                               osrfStringArray* map = osrfStringArrayTokenize( string_tmp, ' ' );
-                                               osrfHashSet( _tmp, map, "map");
-
-                                               string_tmp = NULL;
-                                               if( (string_tmp = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
+                                               prop_str = (char*) xmlGetProp(_l, BAD_CAST "map");
+                                               if( prop_str )
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link mapping list is %s", prop_str );
+                                               osrfStringArray* map = osrfStringArrayTokenize( prop_str, ' ' );
+                                               osrfHashSet( link_def_hash, map, "map");
+
+                                               if( (prop_str = (char*)xmlGetProp(_l, BAD_CAST "field")) ) {
                                                        osrfHashSet(
-                                                               _tmp,
-                                                               strdup( string_tmp ),
+                                                               link_def_hash,
+                                                               strdup( prop_str ),
                                                                "field"
                                                        );
-                                               }
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link fclass is %s", prop_str );
+                                               } else
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Link with no fclass" );
 
                                                osrfHashSet(
-                                                       links,
-                                                       _tmp,
-                                                       strdup( string_tmp )
+                                                       current_links_hash,
+                                                       link_def_hash,
+                                                       prop_str
                                                );
 
-                                               osrfLogDebug(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
-
                                                _l = _l->next;
                                        }
                                }
@@ -265,7 +258,7 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
 **** Structure of permacrud in memory ****/
 
                                if (!strcmp( (char*)_cur->name, "permacrud" )) {
-                                       osrfHashSet( usrData, pcrud, "permacrud" );
+                                       osrfHashSet( class_def_hash, pcrud, "permacrud" );
                                        xmlNodePtr _l = _cur->children;
 
                                        while(_l) {
@@ -277,42 +270,44 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
                                                xmlNodePtr _a = _l->children;
 
                                                while(_a) {
+                                                       const char* action_name = (const char*) _a->name;
                                                        if (
-                                                               strcmp( (char*)_a->name, "create" ) &&
-                                                               strcmp( (char*)_a->name, "retrieve" ) &&
-                                                               strcmp( (char*)_a->name, "update" ) &&
-                                                               strcmp( (char*)_a->name, "delete" )
+                                                               strcmp( action_name, "create" ) &&
+                                                               strcmp( action_name, "retrieve" ) &&
+                                                               strcmp( action_name, "update" ) &&
+                                                               strcmp( action_name, "delete" )
                                                        ) {
                                                                _a = _a->next;
                                                                continue;
                                                        }
 
-                                                       string_tmp = (char*) _a->name;
-                                                       osrfLogDebug(OSRF_LOG_MARK, "Found Permacrud action %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+                                                       osrfLogDebug(OSRF_LOG_MARK, "Found Permacrud action %s for class %s",
+                                                               action_name, current_class_name );
 
-                                                       _tmp = osrfNewHash();
-                                                       osrfHashSet( pcrud, _tmp, string_tmp );
+                                                       osrfHash* action_def_hash = osrfNewHash();
+                                                       osrfHashSet( pcrud, action_def_hash, action_name );
 
                                                        // Tokenize permission attribute into an osrfStringArray
-                                                       string_tmp = (char*) xmlGetProp(_a, BAD_CAST "permission");
-                                                       if( string_tmp )
+                                                       prop_str = (char*) xmlGetProp(_a, BAD_CAST "permission");
+                                                       if( prop_str )
                                                                osrfLogDebug(OSRF_LOG_MARK,
-                                                                       "Permacrud permission list is %s", string_tmp );
-                                                       osrfStringArray* map = osrfStringArrayTokenize( string_tmp, ' ' );
-                                                       osrfHashSet( _tmp, map, "permission");
+                                                                       "Permacrud permission list is %s", prop_str );
+                                                       osrfStringArray* map = osrfStringArrayTokenize( prop_str, ' ' );
+                                                       osrfHashSet( action_def_hash, map, "permission");
 
-                                               osrfHashSet( _tmp, (char*)xmlGetNoNsProp(_a, BAD_CAST "global_required"), "global_required");
+                                               osrfHashSet( action_def_hash,
+                                                               (char*)xmlGetNoNsProp(_a, BAD_CAST "global_required"), "global_required");
 
                                                        // Tokenize context_field attribute into an osrfStringArray
-                                                       string_tmp = (char*) xmlGetProp(_a, BAD_CAST "context_field");
-                                                       if( string_tmp )
+                                                       prop_str = (char*) xmlGetProp(_a, BAD_CAST "context_field");
+                                                       if( prop_str )
                                                                osrfLogDebug(OSRF_LOG_MARK,
-                                                                       "Permacrud context_field list is %s", string_tmp );
-                                                       map = osrfStringArrayTokenize( string_tmp, ' ' );
-                                                       osrfHashSet( _tmp, map, "local_context");
+                                                                       "Permacrud context_field list is %s", prop_str );
+                                                       map = osrfStringArrayTokenize( prop_str, ' ' );
+                                                       osrfHashSet( action_def_hash, map, "local_context");
 
                                                        osrfHash* foreign_context = osrfNewHash();
-                                                       osrfHashSet( _tmp, foreign_context, "foreign_context");
+                                                       osrfHashSet( action_def_hash, foreign_context, "foreign_context");
 
                                                        xmlNodePtr _f = _a->children;
 
@@ -322,39 +317,45 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
                                                                        continue;
                                                                }
 
-                                                               string_tmp = NULL;
-                                                               if( (string_tmp = (char*)xmlGetNoNsProp(_f, BAD_CAST "link")) ) {
-                                                                       osrfLogDebug(OSRF_LOG_MARK, "Permacrud context link definition is %s", string_tmp );
+                                                               if( (prop_str = (char*)xmlGetNoNsProp(_f, BAD_CAST "link")) ) {
+                                                                       osrfLogDebug(OSRF_LOG_MARK,
+                                                                               "Permacrud context link definition is %s", prop_str );
 
-                                                                       osrfHash* _flink = oilsIDLFindPath("/%s/links/%s", osrfHashGet(usrData, "classname"), string_tmp);
-
-                                                                       osrfHashSet( foreign_context, osrfNewHash(), osrfHashGet(_flink, "class") );
-                                                                       osrfHash* _tmp_fcontext = osrfHashGet( foreign_context, osrfHashGet(_flink, "class") );
+                                                                       osrfHash* _tmp_fcontext = osrfNewHash();
 
+                                                                       // Store pointers to elements already stored
+                                                                       // from the <link> aggregate
+                                                                       osrfHash* _flink = osrfHashGet( current_links_hash, prop_str );
                                                                        osrfHashSet( _tmp_fcontext, osrfHashGet(_flink, "field"), "fkey" );
                                                                        osrfHashSet( _tmp_fcontext, osrfHashGet(_flink, "key"), "field" );
 
                                                                        // Tokenize field attribute into an osrfStringArray
-                                                                       string_tmp = (char*) xmlGetProp(_f, BAD_CAST "field");
-                                                                       if( string_tmp )
+                                                                       const char * field_list = (char*) xmlGetProp(_f, BAD_CAST "field");
+                                                                       if( field_list )
                                                                                osrfLogDebug(OSRF_LOG_MARK,
-                                                                                       "Permacrud foreign context field list is %s", string_tmp );
-                                                                       map = osrfStringArrayTokenize( string_tmp, ' ' );
+                                                                                       "Permacrud foreign context field list is %s", field_list );
+                                                                       map = osrfStringArrayTokenize( field_list, ' ' );
                                                                        osrfHashSet( _tmp_fcontext, map, "context");
 
+                                                                       // Insert the new hash into a hash attached to the parent node
+                                                                       osrfHashSet( foreign_context, _tmp_fcontext, osrfHashGet( _flink, "class" ) );
+
                                                                } else {
 
-                                                                       if( (string_tmp = (char*)xmlGetNoNsProp(_f, BAD_CAST "field") )) {
-                                                                               char* map_list = strdup( string_tmp );
-                                                                               osrfLogDebug(OSRF_LOG_MARK, "Permacrud foreign context field list is %s", string_tmp );
+                                                                       if( (prop_str = (char*)xmlGetNoNsProp(_f, BAD_CAST "field") )) {
+                                                                               char* map_list = strdup( prop_str );
+                                                                               osrfLogDebug(OSRF_LOG_MARK,
+                                                                                       "Permacrud foreign context field list is %s", prop_str );
                        
                                                                                if (strlen( map_list ) > 0) {
                                                                                        char* st_tmp = NULL;
                                                                                        char* _map_class = strtok_r(map_list, " ", &st_tmp);
-                                                                                       osrfStringArrayAdd(osrfHashGet( _tmp, "local_context"), _map_class);
+                                                                                       osrfStringArrayAdd(
+                                                                                               osrfHashGet( action_def_hash, "local_context"), _map_class);
                                                                        
                                                                                        while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
-                                                                                               osrfStringArrayAdd(osrfHashGet( _tmp, "local_context"), _map_class);
+                                                                                               osrfStringArrayAdd(
+                                                                                                       osrfHashGet( action_def_hash, "local_context"), _map_class);
                                                                                        }
                                                                                }
                                                                                free(map_list);
@@ -370,12 +371,13 @@ osrfHash* oilsIDLInit( const char* idl_filename ) {
                                }
 
                                if (!strcmp( (char*)_cur->name, "source_definition" )) {
-                                       string_tmp = NULL;
-                                       if( (string_tmp = (char*)xmlNodeGetContent(_cur)) ) {
-                                               osrfLogDebug(OSRF_LOG_MARK, "Using source definition '%s' for class %s", string_tmp, osrfHashGet(usrData, "classname") );
+                                       const char* content_str;
+                                       if( (content_str = (char*)xmlNodeGetContent(_cur)) ) {
+                                               osrfLogDebug(OSRF_LOG_MARK, "Using source definition '%s' for class %s",
+                                                       content_str, current_class_name );
                                                osrfHashSet(
-                                                       usrData,
-                                                       strdup( string_tmp ),
+                                                       class_def_hash,
+                                                       strdup( content_str ),
                                                        "source_definition"
                                                );
                                        }
@@ -416,40 +418,61 @@ osrfHash* oilsIDLFindPath( const char* path, ... ) {
        return obj;
 }
 
+static osrfHash* findClassDef( const char* classname ) {
+       if( !classname || !idlHash )
+               return NULL;
+       else
+               return osrfHashGet( idlHash, classname );
+}
+
 int oilsIDL_classIsFieldmapper ( const char* classname ) {
-       if (!classname) return 0;
-       if(oilsIDLFindPath( "/%s", classname )) return 1;
-       return 0;
+       if( findClassDef( classname ) )
+               return 1;
+       else
+               return 0;
 }
 
 int oilsIDL_ntop (const char* classname, const char* fieldname) {
-       osrfHash* _pos = NULL;
+       osrfHash* class_def_hash = findClassDef( classname );
+       if( !class_def_hash )
+               return -1;                      // No such class
+       
+       osrfHash* fields_hash = osrfHashGet( class_def_hash, "fields" );
+       if( !fields_hash )
+               return -1;                      // No list of fields fo the class
+
+       osrfHash* field_def_hash = osrfHashGet( fields_hash, fieldname );
+       if( !field_def_hash )
+               return -1;                      // No such field
 
-       if (!oilsIDL_classIsFieldmapper(classname)) return -1;
-       _pos = oilsIDLFindPath( "/%s/fields/%s", classname, fieldname );
-       if (_pos) return atoi( osrfHashGet(_pos, "array_position") );
-       return -1;
+       const char* pos_attr = osrfHashGet( field_def_hash, "array_position" );
+       if( !pos_attr )
+               return -1;                      // No array_position attribute
+
+       return atoi( pos_attr );        // Return position as int
 }
 
 char * oilsIDL_pton (const char* classname, int pos) {
-       char* ret = NULL;
-       osrfHash* f = NULL;
-       osrfHash* fields = NULL;
-       osrfHashIterator* itr = NULL;
-
-       if (!oilsIDL_classIsFieldmapper(classname)) return NULL;
+       osrfHash* class_def_hash = findClassDef( classname );
+       if( !class_def_hash )
+               return NULL;            // No such class
+       
+       osrfHash* fields_hash = osrfHashGet( class_def_hash, "fields" );
+       if( !fields_hash )
+               return NULL;            // No list of fields fo the class
 
-       fields = oilsIDLFindPath( "/%s/fields", classname );
-       itr = osrfNewHashIterator( fields );
+       char* ret = NULL;
+       osrfHash* field_def_hash = NULL;
+       osrfHashIterator* iter = osrfNewHashIterator( fields_hash );
 
-       while ( (f = osrfHashIteratorNext( itr )) ) {
-               if ( atoi(osrfHashGet(f, "array_position")) == pos ) {
-                       ret = strdup(osrfHashIteratorKey(itr));
+       while ( ( field_def_hash = osrfHashIteratorNext( iter ) ) ) {
+               if ( atoi( osrfHashGet( field_def_hash, "array_position" ) ) == pos ) {
+                       ret = strdup( osrfHashIteratorKey( iter ) );
                        break;
                }
        }
 
-       osrfHashIteratorFree( itr );
+       osrfHashIteratorFree( iter );
 
        return ret;
 }
index 78d77f7..d12f82e 100644 (file)
@@ -1621,7 +1621,17 @@ sub all_rec_holds {
        $args ||= { fulfillment_time => undef };
        $args->{cancel_time} = undef;
 
-       my $resp = { volume_holds => [], copy_holds => [] };
+       my $resp = { volume_holds => [], copy_holds => [], metarecord_holds => [] };
+
+    my $mr_map = $e->search_metabib_metarecord_source_map({source => $title_id})->[0];
+    if($mr_map) {
+        $resp->{metarecord_holds} = $e->search_action_hold_request(
+            {   hold_type => OILS_HOLD_TYPE_METARECORD,
+                target => $mr_map->metarecord,
+                %$args 
+            }, {idlist => 1}
+        );
+    }
 
        $resp->{title_holds} = $e->search_action_hold_request(
                { 
index 3bdd882..4ca56b5 100644 (file)
@@ -133,6 +133,19 @@ sub record_id_to_mods_slim {
 }
 
 
+
+__PACKAGE__->register_method(
+       method  => "record_id_to_mods_slim_batch",
+       api_name        => "open-ils.search.biblio.record.mods_slim.batch.retrieve",
+    stream => 1
+);
+sub record_id_to_mods_slim_batch {
+       my($self, $conn, $id_list) = @_;
+    $conn->respond(_records_to_mods($_)->[0]) for @$id_list;
+    return undef;
+}
+
+
 # Returns the number of copies attached to a record based on org location
 __PACKAGE__->register_method(
        method  => "record_id_to_copy_count",
index 3e3f7b9..2b60b57 100644 (file)
@@ -146,7 +146,9 @@ sub id {
 
 sub title_id {
     my $self = shift;
-    return ($self->{mods}) ? $self->{mods}->title : $self->{copy}->dummy_title;
+    my $t =  ($self->{mods}) ? $self->{mods}->title : $self->{copy}->dummy_title;
+    $t =~ s/\pM+//og;
+    return $t;
 }
 
 sub permanent_location {
index 7576b9b..44897cc 100644 (file)
@@ -183,7 +183,7 @@ sub session {
                }
 
                $self->{session}->connect if $self->{xact} or $self->{connect} or $always_xact;
-               $self->xact_start if $self->{xact} or $always_xact;
+               $self->xact_begin if $self->{xact} or $always_xact;
        }
 
     $xact_ed_cache{$self->{xact_id}} = $self if $always_xact;
@@ -194,12 +194,13 @@ sub session {
 # -----------------------------------------------------------------------------
 # Starts a storage transaction
 # -----------------------------------------------------------------------------
-sub xact_start {
+sub xact_begin {
        my $self = shift;
-       $self->log(D, "starting new db session");
+       $self->log(D, "starting new database transaction");
        my $stat = $self->request($self->app . '.transaction.begin') unless $self->{xact_id};
        $self->log(E, "error starting database transaction") unless $stat;
     $self->{xact_id} = $stat;
+    $self->{xact} = 1;
        return $stat;
 }
 
@@ -213,6 +214,7 @@ sub xact_commit {
        my $stat = $self->request($self->app.'.transaction.commit');
        $self->log(E, "error comitting database transaction") unless $stat;
     delete $self->{xact_id};
+    delete $self->{xact};
        return $stat;
 }
 
@@ -221,15 +223,51 @@ sub xact_commit {
 # -----------------------------------------------------------------------------
 sub xact_rollback {
        my $self = shift;
-   return unless $self->{session} and $self->{xact_id};
+    return unless $self->{session} and $self->{xact_id};
        $self->log(I, "rolling back db session");
        my $stat = $self->request($self->app.".transaction.rollback");
        $self->log(E, "error rolling back database transaction") unless $stat;
     delete $self->{xact_id};
+    delete $self->{xact};
        return $stat;
 }
 
 
+# -----------------------------------------------------------------------------
+# Savepoint functions.  If no savepoint name is provided, the same name is used 
+# for each successive savepoint, in which case only the last savepoint set can 
+# be released or rolled back.
+# -----------------------------------------------------------------------------
+sub set_savepoint {
+    my $self = shift;
+    my $name = shift || 'savepoint';
+    return unless $self->{session} and $self->{xact_id};
+       $self->log(I, "setting savepoint '$name'");
+       my $stat = $self->request($self->app.".savepoint.set")
+           or $self->log(E, "error setting savepoint '$name'");
+    return $stat;
+}
+
+sub release_savepoint {
+    my $self = shift;
+    my $name = shift || 'savepoint';
+    return unless $self->{session} and $self->{xact_id};
+       $self->log(I, "releasing savepoint '$name'");
+       my $stat = $self->request($self->app.".savepoint.release")
+        or $self->log(E, "error releasing savepoint '$name'");
+    return $stat;
+}
+
+sub rollback_savepoint {
+    my $self = shift;
+    my $name = shift || 'savepoint';
+    return unless $self->{session} and $self->{xact_id};
+       $self->log(I, "rollback savepoint '$name'");
+       my $stat = $self->request($self->app.".savepoint.rollback")
+        or $self->log(E, "error rolling back savepoint '$name'");
+    return $stat;
+}
+
 
 # -----------------------------------------------------------------------------
 # Rolls back the transaction and disconnects
@@ -237,14 +275,13 @@ sub xact_rollback {
 sub rollback {
        my $self = shift;
        $self->xact_rollback;
-   delete $self->{xact};
        $self->disconnect;
 }
 
 sub disconnect {
        my $self = shift;
        $self->session->disconnect if $self->{session};
-   delete $self->{session};
+    delete $self->{session};
 }
 
 
index a5a37e8..61c38e7 100644 (file)
@@ -1028,6 +1028,7 @@ patron.holds.prototype = {
                     holds = holds.concat( robj.copy_holds );
                     holds = holds.concat( robj.volume_holds );
                     holds = holds.concat( robj.title_holds );
+                    holds = holds.concat( robj.metarecord_holds );
                     holds = holds.sort();
                 }
                        } else {