<?xml version="1.0"?>

<!-- 

    that is a sample ARDB core configuration file.  it's structure
    well may change.

    $Id: configuration.xml,v 1.1.1.1 2003/07/09 12:18:51 vano Exp $
-->

<!DOCTYPE configuration [

<!ELEMENT configuration 
    ( relation-type | put-processing | table 
    | field-attribute-mapping | perl-module )* >

<!ELEMENT relation-type ( view )*>
<!ATTLIST relation-type name             CDATA #REQUIRED>
<!ATTLIST relation-type default-retrieve CDATA #REQUIRED>
<!ATTLIST relation-type reverse          CDATA #IMPLIED>
<!ATTLIST relation-type undirected       CDATA #IMPLIED>

<!ELEMENT view EMPTY>
<!ATTLIST view name     CDATA #REQUIRED>
<!ATTLIST view retrieve CDATA #REQUIRED>

<!ELEMENT perl-module EMPTY>
<!ATTLIST perl-module name CDATA #REQUIRED>

<!ELEMENT table ( field | create-table-sql )*>

<!ELEMENT put-processing ( 
   store-to-table | 
   call-function | 
   build-forward-relation | 
   build-backward-relation )* >
<!ATTLIST put-processing record-type CDATA #REQUIRED>
<!ATTLIST put-processing attributes  CDATA #IMPLIED>


<!ELEMENT field-associations EMPTY>

<!ELEMENT field-attribute-mapping ( field-associations ) >

<!ATTLIST field-attribute-mapping name     CDATA #IMPLIED>
<!ATTLIST field-attribute-mapping based-on CDATA #IMPLIED>

<!ELEMENT store-to-table (field-attribute-mapping?)>
<!ATTLIST store-to-table table                   CDATA #REQUIRED >
<!ATTLIST store-to-table field-attribute-mapping CDATA #IMPLIED >

<!ELEMENT build-forward-relation EMPTY>
<!ATTLIST build-forward-relation type CDATA #REQUIRED>
<!ATTLIST build-forward-relation attributes CDATA #REQUIRED>

<!ELEMENT build-backward-relation EMPTY>
<!ATTLIST build-backward-relation type CDATA #REQUIRED>
<!ATTLIST build-backward-relation attributes CDATA #REQUIRED>


]>


<configuration>


<!--
 
    Root-level relation elements define relation types.  

    Relation types are only used at get_full_record()
    operations.

    Each relation type must have a unique id. It is a bad idea 
    to give relation type an id equal to any existing 
    ReDIF attribute.  That's because of the way we going to use
    the relation type ids: they may serve as attributes in unfolded
    templates.  Another approach may be to stick to a special 
    convention on relation type ids: e.g. using Title Like 
    First-Caps Case.  

    See lib/ARDB/RelationType.pm for more details.
    

    'reverse' attribute specifies the opposite of this type of
    relation by giving its id name.

    'undirected' attribute means the relation is valid in both
    directions: both from subject to the object and from object to the
    subject.  It makes no sense in presence of the 'reverse'
    attribute, should trigger an error.  Accepts logical values: 
      yes | true | 1 | no | false | 0 (case insensitive) 

    'default-retrieve' attribute specifies what to add to the bare
    template upon get_full_template() request, which finds such a
    relationship to or from the template.  accepted values: nothing,
    record, ID or specific attribute of the related record

-->

<relation-type name="written-by" reverse="wrote" default-retrieve="ID" />

<relation-type 
	name="wrote"
	reverse="written-by"
	default-retrieve="record">

	<!-- 
		when we say retrieve we mean retrieve from the 
		relation object template to include 
		the retrieved data into the requested "full" template
	-->

	<view name="brief" retrieve="title,id:handle,authors:author/name" />

	<view name="brief-with-creation-date" retrieve="title,handle,authors:author/name,creation-date"/>

</relation-type>

<relation-type
    name="affiliated-with" 
    reverse="affiliates"
    default-retrieve="record">
    <view name='brief' retrieve='name,id:handle,location'/>

</relation-type>


<relation-type
    name="affiliates"
    default-retrieve="record">

    <view name='brief' retrieve='fname,id:handle'/>

</relation-type>



<!--

<relation-type 
	name="cited-by"
	reverse="cites" 
	>
</relation-type>

-->

<relation-type
	name="rejected-authorship"
	undirected="yes"
	default-retrieve="ID"
/>


<!--
 	A table element configures an SQL table. 

 	It only defines table structure and SQL details.

 	What it does not define is mapping from template data to table
 	records.

-->


<table name="persons">
	<field name="fname"   sql-type=" VARCHAR(200) NOT NULL "/>
	<field name="email"  sql-type=" VARCHAR(200) " />
	<field name="handle" sql-type=" VARCHAR(200) NOT NULL PRIMARY KEY " />

 	<!-- 
		upon building create table statement this will be included
	-->
	<create-table-sql line=" "/>

</table>


<table name="documents">

	<field name="title"    sql-type=" VARCHAR(200) NOT NULL "/>
	<field name="authors"  sql-type=" CHAR(200) NOT NULL "/>
	<field name="authors_emails"  sql-type=" CHAR(200) NOT NULL "/>
	<field name="subject"  sql-type=" TEXT NOT NULL" />
	<field name="abstract" sql-type=" TEXT " />
	<field name="creation_date"  
			       sql-type=" TIMESTAMP(14) " />
	<field name="handle"   sql-type=" CHAR(200) NOT NULL PRIMARY KEY " />

	<field name="jel"      sql-type=" CHAR(50) " />

	<field name="file"     sql-type=" int " />
	<field name="urls"     sql-type=" text "/>

        <field name='keywords' sql-type=" text "/>

 	<!-- 
		upon composing SQL create table statement
		this will be included:
	-->

	<create-table-sql>
	  INDEX title_i ( title ),
          INDEX authors_i ( authors ),
          INDEX creationdate_i ( creation_date ),
	  FULLTEXT INDEX subj ( title, keywords, abstract )
	</create-table-sql>

</table>




<table name="catalog">

	<field name="title"    sql-type=" VARCHAR(200) NOT NULL "/>
	<field name="authors"  sql-type=" CHAR(200) NOT NULL "/>
	<field name="authors_emails"  sql-type=" CHAR(200) NOT NULL "/>
	<field name="subject"  sql-type=" TEXT NOT NULL" />
	<field name="abstract" sql-type=" TEXT " />
	<field name="creation_date"  
			       sql-type=" TIMESTAMP(14) " />
	<field name="handle"   sql-type=" CHAR(200) NOT NULL PRIMARY KEY " />

	<field name="notes"     sql-type=" text "/>
        <field name='keywords' sql-type=" text "/>
</table>

<!-- 
  When there is a put_template() operation, the template data 
  may need to be stored in some SQL tables.  To do that we have tables
  and we need a mapping, which would tell what data to put into which
  table fields.
  But some template types are similar and their mapping will be similar.
  Therefore we create reusable named field-to-attribute maps.
-->

<field-attribute-mapping name="documents">
	<field-associations
		title="title"
		subject="title,abstract,keywords"
		authors="author/name"
		authors_emails="author/email"
		keywords="keywords"
		abstract="abstract"
		creation_date="creation-date"
		handle="handle"
 />

<!-- 
XXX:
		special_field="My::ARDB::special_field_filter"
-->
</field-attribute-mapping>



<!-- XXX -->
<perl-module name="My::ARDB"/>

<put-processing record-type="ReDIF-Person 1.0">

  <store-to-table table="persons">
    <field-attribute-mapping>
	
	<field-associations  
	   fname="name-full"
           id   ="handle"
           email="email"/>

      </field-attribute-mapping>
    </store-to-table>


  <build-forward-relation 
    type="wrote" 
    attributes="author-paper,author-article,author-software,author-book,author-chapter"
    />

  <build-forward-relation 
    type="affiliated-with" 
    attributes="workplace-institution"
    />

</put-processing>


<put-processing record-type="ReDIF-Institution 1.0">
</put-processing>


<put-processing record-type="ReDIF-Paper 1.0,ReDIF-Article 1.0,ReDIF-Book 1.0,ReDIF-Software 1.0">

    <store-to-table 
      table="documents"
      field-attribute-mapping="documents"/>
    
    <store-to-table table="catalog">
      <field-attribute-mapping based-on="documents">
	
	<!--

	This is an anonymous field-attribute-mapping.  But it must be
	stored in the configuration together with named mappings, but 
	with some made-up id, like for instance "#9", used in example 
	perl code above.  This mapping is based on "documents" mapping,
	therefore it inherits all the fields from it, but adds or replaces 
	the "notes" field:

	-->

	<field-associations  notes="issue, year, volume" />

      </field-attribute-mapping>
    </store-to-table>
    
   <!--
    <call-perl-function name="My::ARDB::put_paper"/>
    -->
    
    <build-forward-relation 
      type="written-by" 
      attributes="author/handle"
      />

    <build-forward-relation 
      type="written-by" 
      attributes="author/email"
      />

</put-processing>


<delete-processing record-type="ReDIF-Paper 1.0,ReDIF-Article 1.0,ReDIF-Book 1.0,ReDIF-Software 1.0">

   <delete-from-table table="documents" by='handle' />
   <delete-from-table table="catalog"   by='handle' />

</delete-processing>


<![CDATA[

<put-processing record-type="ReDIF-Archive 1.0">
    <store-to-table table="archives">

      <!--
      
      here is another example of anonymous mapping.  
      This time without based-on attribute.
      
      -->

      <field-attribute-mapping>
	<field-associations
	  name="name"
	  handle="handle"
	  URL="URL" />
      </field-attribute-mapping>
    </store-to-table>
</put-processing>

<put-processing record-type="ReDIF-Series 1.0">
    <store-to-table table="series">
      <field-attribute-mapping>
	<field-associations
	  name="name"
	  handle="handle"
	  URL="URL" />
      </field-attribute-mapping>
    </store-to-table>
    <call-perl-function name="ARDB::Addon::series_template"/>
    <build-forward-relation 
      type="is-part-of" attributes="Archive"/>

</put-processing>

  <!--  #####################################################
         delete processing
       #####################################################  -->

 <delete-processing record-type="ReDIF-Archive 1.0">

   <delete-from-table  table='archives'  by='handle' />

   <call-perl-function name='ARDB::Addon::archive_deleted' />

 </delete-processing>

]]>


</configuration>



<!-- 


  put-processing configuration sections define how a template is processed
  upon a put template operation.

  Each put-processing element MUST have:

     "record-type" attribute with a list of template-types 
  
  and MAY have:

     "attribute" attribute with a list of attribute-specifications

  Then it allows following children, which specify the processing actions:

     store-to-table ...
     call-function ...
     build-forward-relation 
     build-backward-relation 

  Each put-processing section should be compiled by the ARDB::Configuration module to some 
  perlcode.  It might go like this:

perl:

  # standard stub

  my $ARDB     = shift;
  my $template = shift;
  my $relations = shift;  # An object to accumulate the relations

  my $tt       = $template->{'template-type'} [0];
  my $handle   = $template->{'handle'} [0];

  my $configuration  = $ARDB -> configuration;  


  # store-to-table action
  { 
     my $map = $configuration -> table_mapping( "documents" ) ;
     my $record = $map -> produce_record ( $template );
     my $table  = $configuration -> table( "documents" );
     $table -> store_record ( $record );
  }

  # call-perl-function action
  &My::ARDB::put_paper( $ARDB, $template );

  # another store-to-table action
  { 
     my $map = $configuration -> table_mapping( "#9" ) ;
     my $record = $map -> produce_record ( $template );
     my $table  = $configuration -> table( "catalog" );
     $table -> store_record ( $record );
  }


  # build-forward-relation action
  { 
     my $rel_name = "written-by";
     my $source   = $handle;
     my @values   = get_values_by_attribute_path( $template, "author/handle" );
     foreach ( @values ) {
        # not exactly like this, but should give you an idea.
        # not like this because we need to collect all template's relations
        # and compare it to the existing ones before we write them 
        # to the relations table
        $relations->new_relation( $handle, $rel_name, $_, $source );
     }
  }

  # that's it

  here are the sample put-processing configuration sections

-->




