ARSperl

 view release on metacpan or  search on metacpan

ARS.xs  view on Meta::CPAN

			int i;
			HV *h;

			if( (items - staticParams) % 2 ){
				(void) ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_ARGS);
#ifdef PROFILE
				AP_FREE(ctrl); /* invalid, cleanup */
#else
				safefree(ctrl);
#endif
				goto ar_login_end;
			}

			h = newHV();			
			for( i = staticParams; i < items; i+=2 ){
				hv_store_ent( h, newSVsv(ST(i)), newSVsv(ST(i+1)), 0 );
			}

			if( hv_exists(h,"charSet",7) ){
				strncpy( ctrl->localeInfo.charSet, SvPV_nolen( *(hv_fetch(h,"charSet",7,0)) ), AR_MAX_LANG_SIZE );
			}
			if( hv_exists(h,"timeZone",8) ){
				strncpy( ctrl->localeInfo.timeZone, SvPV_nolen( *(hv_fetch(h,"timeZone",8,0)) ), AR_MAX_LOCALE_SIZE );
			}
			if( hv_exists(h,"customDateFormat",16) ){
				strncpy( ctrl->localeInfo.customDateFormat, SvPV_nolen( *(hv_fetch(h,"customDateFormat",16,0)) ), AR_MAX_FORMAT_SIZE );
			}
			if( hv_exists(h,"customTimeFormat",16) ){
				strncpy( ctrl->localeInfo.customTimeFormat, SvPV_nolen( *(hv_fetch(h,"customTimeFormat",16,0)) ), AR_MAX_FORMAT_SIZE );
			}
			if( hv_exists(h,"separators",10) ){
				strncpy( ctrl->localeInfo.separators, SvPV_nolen( *(hv_fetch(h,"separators",10,0)) ), AR_MAX_LANG_SIZE );
			}

			hv_undef( h );
		}
#endif
#if AR_EXPORT_VERSION >= 7L
		ctrl->authString[0] = 0;
		if ( CVLD(authString) ) {
			strncpy(ctrl->authString, authString, AR_MAX_NAME_SIZE);
		}
#endif
#if AR_EXPORT_VERSION >= 4
		/* call ARInitialization */
		ret = ARInitialization(ctrl, &status);

		if(ARError(ret, status)) {
			DBG( ("ARInitialization failed %d\n", ret) );
			ARTermination(ctrl, &status);
			ARError(ret, status);
#ifdef PROFILE
			AP_FREE(ctrl);
#else
			safefree(ctrl);
#endif
			goto ar_login_end;
		}

		/*
		printf( "ctrl->localeInfo.customDateFormat <%s>\n", ctrl->localeInfo.customDateFormat );
		printf( "ctrl->localeInfo.separators <%s>\n",       ctrl->localeInfo.separators );
		*/
#endif

		if (!server || !*server) {
			DBG( ("no server given. picking one.\n") );
#if AR_EXPORT_VERSION >= 4
	  		ret = ARGetListServer(ctrl, &serverList, &status);
#else
	  		ret = ARGetListServer(&serverList, &status);
#endif
	  		if (ARError( ret, status)) {
				ARTermination(ctrl, &status);
				ARError(ret, status);
#ifdef PROFILE
				AP_FREE(ctrl); /* invalid, cleanup */
#else
				safefree(ctrl);
#endif
				
				DBG( ("ARGetListServer failed %d\n", ret) );
	   			goto ar_login_end;
	  		}
			status.numItems = 0;
	  		if (serverList.numItems == 0) {
				DBG( ("serverList is empty.\n") );
	     			(void) ARError_add( AR_RETURN_ERROR, AP_ERR_NO_SERVERS);
				ARTermination(ctrl, &status);
				ARError(ret, status);
#ifdef PROFILE
				AP_FREE(ctrl); /* invalid, cleanup */
#else
				safefree(ctrl);
#endif
				goto ar_login_end;
	    		}
	    		server = serverList.nameList[0];
			DBG( ("changing s_ok to 0, picked server %s\n",
				SAFEPRT(server)) );
	    		s_ok = 0;
	  	}
	  	strncpy(ctrl->server, server, sizeof(ctrl->server));
	 	ctrl->server[sizeof(ctrl->server)-1] = 0;

		/* set the tcp/rpc port if given */

		ret = ARSetServerPort(ctrl, ctrl->server, tcpport, rpcnumber,
					&status);
		if (ARError(ret, status)) {
			DBG( ("ARSetServerPort failed %d\n", ret) );
			ARTermination(ctrl, &status);
			ARError(ret, status);
#ifdef PROFILE
			AP_FREE(ctrl);
#else
			safefree(ctrl);
#endif
			RETVAL = NULL;
 			goto ar_login_end;
		}

	  	/* finally, check to see if the user id is valid */

	  	ret = ARVerifyUser(ctrl, NULL, NULL, NULL, &status);
	  	if(ARError( ret, status)) {
			DBG( ("ARVerifyUser failed %d\n", ret) );
			ARTermination(ctrl, &status);
			ARError(ret, status);
#ifdef PROFILE
			AP_FREE(ctrl); /* invalid, cleanup */
#else
			safefree(ctrl);
#endif
			RETVAL = NULL;
	  	} else {
	  		RETVAL = ctrl; /* valid, return ctrl struct */
	  	}

	  	if(s_ok == 0) {
			DBG( ("s_ok == 0, cleaning ServerNameList\n") );
	  		FreeARServerNameList(&serverList, FALSE);
	  	}
	ar_login_end:;
		DBG( ("finished.\n") );
	}
	OUTPUT:
	RETVAL

HV*
ars_VerifyUser(ctrl)
	ARControlStruct *	ctrl
	CODE:
	{
		int ret = 0;
		ARBoolean	adminFlag  = 0,
				subAdminFlag = 0,
				customFlag   = 0; 
		ARStatusList status;

		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);

		ret = ARVerifyUser( ctrl, &adminFlag, &subAdminFlag, &customFlag, &status );

		/* printf( "ret = %d, adminFlag = %d, subAdminFlag = %d, customFlag = %d\n",
			ret, adminFlag, subAdminFlag, customFlag ); */

		if(! ARError(ret, status)) {
		    RETVAL = newHV();
		    sv_2mortal( (SV*) RETVAL );

			hv_store( RETVAL, "adminFlag",    strlen("adminFlag"),    newSViv(adminFlag),    0);
			hv_store( RETVAL, "subAdminFlag", strlen("subAdminFlag"), newSViv(subAdminFlag), 0);
			hv_store( RETVAL, "customFlag",   strlen("customFlag"),   newSViv(customFlag),   0);
		}else{
			XSRETURN_UNDEF;
		}
	}
	OUTPUT:
	RETVAL

void
ars_GetControlStructFields(ctrl)
	ARControlStruct *	ctrl
	PPCODE:
	{
	   (void) ARError_reset();
	   if(!ctrl) return;
	   XPUSHs(sv_2mortal(newSViv(ctrl->cacheId)));
	   XPUSHs(sv_2mortal(newSViv(ctrl->operationTime)));
	   XPUSHs(sv_2mortal(newSVpv(ctrl->user, 0)));
	   XPUSHs(sv_2mortal(newSVpv(ctrl->password, 0)));
#ifndef AR_MAX_LOCALE_SIZE
	   XPUSHs(sv_2mortal(newSVpv(ctrl->language, 0)));
#else
	   XPUSHs(sv_2mortal(newSVpv(ctrl->localeInfo.locale, 0)));
#endif
	   XPUSHs(sv_2mortal(newSVpv(ctrl->server, 0)));
	   XPUSHs(sv_2mortal(newSViv(ctrl->sessionId)));
#if AR_EXPORT_VERSION >= 7
	   XPUSHs(sv_2mortal(newSVpv(ctrl->authString, 0)));
#endif
	}

SV *
ars_GetCurrentServer(ctrl)
	ARControlStruct *	ctrl
	CODE:
	{
	  RETVAL = NULL;
	  (void) ARError_reset();
	  if(ctrl && ctrl->server) {
	    RETVAL = newSVpv( ctrl->server, strlen(ctrl->server) );
	  } 
	}
	OUTPUT:
	RETVAL

HV *
ars_GetProfileInfo(ctrl)
	ARControlStruct *	ctrl
	CODE:
	{
	  RETVAL = newHV();
	  sv_2mortal( (SV*) RETVAL );

ARS.xs  view on Meta::CPAN

	  while( (hval = hv_iternextsv(fields,&hkey,&klen)) ){
		if( strcmp(hkey,"0") == 0 )  continue;
		h = (HV* ) SvRV(hval);
		hvalName = hv_fetch( h, "name", 4, 0 );
		XPUSHs( sv_2mortal(newSVsv(*hvalName)) );
		XPUSHs( sv_2mortal(newSVpv(hkey,0)) );
	  }

	  get_fieldtable_end:;
	  if( ! fields ){
	    XSRETURN_UNDEF;
	  }
	}

SV *
ars_CreateEntry(ctrl,schema,...)
	ARControlStruct *	ctrl
	char *			schema
	CODE:
	{
	  int               a = 0, 
			    i = 0,
			    c = (items - 2) / 2;
	  AREntryIdType     entryId;
	  ARFieldValueList  fieldList;
	  ARInternalIdList  getFieldIds; 
	  ARStatusList      status;
	  int               ret = 0, rv = 0;
	  unsigned int      dataType = 0, j = 0;
	  HV               *cacheFields;
	  
	  RETVAL=NULL;
	  (void) ARError_reset();
	  Zero(&entryId, 1, AREntryIdType);
	  Zero(&fieldList, 1, ARFieldValueList);
	  Zero(&getFieldIds, 1, ARInternalIdList);
	  Zero(&status, 1, ARStatusList);
	  if (((items - 2) % 2) || c < 1) {
	    (void) ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_ARGS);
	  } else {

	    cacheFields = fieldcache_get_schema_fields( ctrl, schema, FALSE );
	    if( ! cacheFields ){
	      goto create_entry_end;
	    }

	    fieldList.numItems = c;
	    AMALLOCNN(fieldList.fieldValueList,c,ARFieldValueStruct);

	    getFieldIds.numItems = 0;
	    getFieldIds.internalIdList = NULL;

	    /* try to get data type from field cache, collect fieldIds which are not cached */
	    for (i=0; i<c; ++i) {
	      ARInternalId fieldId;
	      a = i*2+2;
	      fieldId = fieldList.fieldValueList[i].fieldId = SvIV(ST(a));

	      dataType = fieldcache_get_data_type( cacheFields, fieldId );
	      if (dataType <= AR_DATA_TYPE_MAX_TYPE) {
	        /* printf( "%s [%d] found in cache\n", schema, fieldId ); fflush(stdout); */ /* _DEBUG_ */
	        if (sv_to_ARValue(ctrl, ST(a+1), dataType, &fieldList.fieldValueList[i].value) < 0) {
	          goto create_entry_end;
	        }
		  }else{
		    if( getFieldIds.numItems == 0 ){
	          AMALLOCNN(getFieldIds.internalIdList,c,ARInternalId);
	        }
	        /* printf( "%s [%d] collect for loading\n", schema, fieldId ); fflush(stdout); */ /* _DEBUG_ */
            getFieldIds.internalIdList[getFieldIds.numItems] = fieldId;
		  	++getFieldIds.numItems;
		  }
	    }

	    /* load missing fields into cache */
	    if( getFieldIds.numItems > 0 ){
	      /* printf( "--- load missing fields ---\n" ); fflush(stdout); */ /* _DEBUG_ */
	      /* if( fieldcache_load_schema(ctrl,schema,&getFieldIds,NULL) != AR_RETURN_OK ){ */
	      if( fieldcache_load_schema(ctrl,schema,&getFieldIds,NULL) > AR_RETURN_WARNING ){
	        goto create_entry_end;
	      }
	    }

	    /* now get data type from the freshly cached fields */
	    i = 0;
	    for (j=0; j<getFieldIds.numItems; ++j) {
	      ARInternalId fieldId = getFieldIds.internalIdList[j];
	      while(fieldId != fieldList.fieldValueList[i].fieldId) ++i;
	      a = i*2+2;

	      dataType = fieldcache_get_data_type( cacheFields, fieldId );
	      if (dataType <= AR_DATA_TYPE_MAX_TYPE) {
	        /* printf( "%s [%d] freshly loaded\n", schema, fieldId ); fflush(stdout); */ /* _DEBUG_ */
	        if (sv_to_ARValue(ctrl, ST(a+1), dataType, &fieldList.fieldValueList[i].value) < 0) {
	          goto create_entry_end;
	        }
		  }else{
		    char errTxt[256];
	        sprintf( errTxt, "Failed to fetch field %d from hash", fieldId );
	        ARError_add(AR_RETURN_ERROR, AP_ERR_FIELD_TYPE);
	        ARError_add(AR_RETURN_ERROR, AP_ERR_CONTINUE, errTxt );
	        goto create_entry_end;
		  }
	    }
	    /* printf( "--------------------\n" ); fflush(stdout); */ /* _DEBUG_ */

	    ret = ARCreateEntry(ctrl, schema, &fieldList, entryId, &status);
#ifdef PROFILE
	    ((ars_ctrl *)ctrl)->queries++;
#endif
	    if (! ARError( ret, status)) rv = 1;
	  create_entry_end:;
	    if(rv == 0) {
	      RETVAL = newSVsv(&PL_sv_undef);
	    } else {
	      RETVAL = newSVpv( entryId, strlen(entryId) );
	    }
			AP_FREE(fieldList.fieldValueList);
	    if( getFieldIds.internalIdList != NULL ) AP_FREE(getFieldIds.internalIdList);
	  }
	}
	OUTPUT:
	RETVAL

int
ars_DeleteEntry(ctrl,schema,entry_id)
	ARControlStruct *	ctrl
	char *			schema
	char *			entry_id
	CODE:
	{
	  int            ret = 0;
	  ARStatusList   status;
#if AR_EXPORT_VERSION >= 3
	  AREntryIdList  entryList;

	  RETVAL = 0; /* assume error */
	  (void) ARError_reset();
	  Zero(&status, 1, ARStatusList);
	  if(perl_BuildEntryList(ctrl, &entryList, entry_id) != 0)
		goto delete_fail;
	  ret = ARDeleteEntry(ctrl, schema, &entryList, 0, &status);
	  if (entryList.entryIdList) AP_FREE(entryList.entryIdList);
#else /* ARS 2 */
	  RETVAL = 0; /* assume error */
	  if(!entry_id || !*entry_id) {
		ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_EID);
		goto delete_fail;
	  }
	  ret = ARDeleteEntry(ctrl, schema, entry_id, &status);
#endif
#ifdef PROFILE
	  ((ars_ctrl *)ctrl)->queries++;
#endif
	  if (ARError(ret, status))
	    RETVAL = 0;
	  else
	    RETVAL = 1;
	delete_fail:;
	}
	OUTPUT:
	RETVAL

void
ars_GetEntryBLOB(ctrl,schema,entry_id,field_id,locType,locFile=NULL)

ARS.xs  view on Meta::CPAN

	char *			entry_id
	unsigned long		getTime
	CODE:
	{
	  int              a = 0, i = 0, c = (items - 4) / 2;
	  int              offset = 4;
	  ARFieldValueList fieldList;
	  ARInternalIdList getFieldIds;
	  ARStatusList     status;
	  int              ret = 0;
	  unsigned int     dataType = 0, j = 0;
	  unsigned int     option = AR_JOIN_SETOPTION_NONE;
	  AREntryIdList    entryList;
	  HV              *cacheFields;

	  (void) ARError_reset();
	  Zero(&status, 1,ARStatusList);
	  Zero(&fieldList, 1, ARFieldValueList);
	  Zero(&getFieldIds, 1, ARInternalIdList);
	  Zero(&entryList, 1,AREntryIdList);
	  RETVAL = 0; /* assume error */
	  if ((items - 4) % 2) {
	    option = SvIV(ST(offset));
	    offset ++;
	  }
	  if (c < 1) {
	    (void) ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_ARGS);
	    goto set_entry_exit;
	  }

	  cacheFields = fieldcache_get_schema_fields( ctrl, schema, FALSE );
	  if( ! cacheFields ){
	    goto set_entry_exit;
	  }

	  fieldList.numItems = c;
	  AMALLOCNN(fieldList.fieldValueList,c,ARFieldValueStruct);

	  getFieldIds.numItems = 0;
	  getFieldIds.internalIdList = NULL;

	  for (i=0; i<c; i++) {
	    ARInternalId fieldId;
	    a = i*2+offset;
	    fieldId = fieldList.fieldValueList[i].fieldId = SvIV(ST(a));
	    
	    if (! SvOK(ST(a+1))) {
	      /* pass a NULL */
	      fieldList.fieldValueList[i].value.dataType = AR_DATA_TYPE_NULL;
	    }else{
	      /* determine data type and pass value */
	      dataType = fieldcache_get_data_type( cacheFields, fieldId );
	      if (dataType <= AR_DATA_TYPE_MAX_TYPE) {
	        if (sv_to_ARValue(ctrl, ST(a+1), dataType, &fieldList.fieldValueList[i].value) < 0) {
		      goto set_entry_end;
	        }
	      }else{
	    	   if( getFieldIds.numItems == 0 ){
	          AMALLOCNN(getFieldIds.internalIdList,c,ARInternalId);
	        }
	        /* printf( "%s [%d] collect for loading\n", schema, fieldId ); fflush(stdout); */ /* _DEBUG_ */
            getFieldIds.internalIdList[getFieldIds.numItems] = fieldId;
	        ++getFieldIds.numItems;
	    	 }
	    }
	  }

	  /* load missing fields into cache */
	  if( getFieldIds.numItems > 0 ){
	    /* printf( "--- load missing fields ---\n" ); fflush(stdout); */ /* _DEBUG_ */
	    /* if( fieldcache_load_schema(ctrl,schema,&getFieldIds,NULL) != AR_RETURN_OK ){ */
	    if( fieldcache_load_schema(ctrl,schema,&getFieldIds,NULL) > AR_RETURN_WARNING ){
	      goto set_entry_end;
	    }
	  }

	  /* now get data type from the freshly cached fields */
	  i = 0;
	  for (j=0; j<getFieldIds.numItems; ++j) {
	    ARInternalId fieldId = getFieldIds.internalIdList[j];
	    while(fieldId != fieldList.fieldValueList[i].fieldId) ++i;
	    a = i*2+offset;

	    dataType = fieldcache_get_data_type( cacheFields, fieldId );
	    if (dataType <= AR_DATA_TYPE_MAX_TYPE) {
	      /* printf( "%s [%d] freshly loaded\n", schema, fieldId ); fflush(stdout); */ /* _DEBUG_ */
	      if (sv_to_ARValue(ctrl, ST(a+1), dataType, &fieldList.fieldValueList[i].value) < 0) {
	        goto set_entry_end;
	      }
		}else{
		  char errTxt[256];
	      sprintf( errTxt, "Failed to fetch field %d from hash", fieldId );
	      ARError_add(AR_RETURN_ERROR, AP_ERR_FIELD_TYPE);
	      ARError_add(AR_RETURN_ERROR, AP_ERR_CONTINUE, errTxt );
	      goto set_entry_end;
		}
	  }
	  /* printf( "--------------------\n" ); fflush(stdout); */ /* _DEBUG_ */


	  /* build entryList */
	  if(perl_BuildEntryList(ctrl, &entryList, entry_id) != 0){
		goto set_entry_end;
	  }

	  ret = ARSetEntry(ctrl, schema, &entryList, &fieldList, getTime, option, &status);
	  if (entryList.entryIdList) AP_FREE(entryList.entryIdList);
#ifdef PROFILE
	  ((ars_ctrl *)ctrl)->queries++;
#endif
	  if (! ARError( ret, status)) {
	    RETVAL = 1;
	  }
	set_entry_end:;
	  if (fieldList.fieldValueList) AP_FREE(fieldList.fieldValueList);
	set_entry_exit:;
	}
	OUTPUT:
	RETVAL

SV *
ars_Export(ctrl,displayTag,vuiType,...)
	ARControlStruct *	ctrl
	char *			displayTag
	unsigned int		vuiType
	CODE:
	{
		int              ret = 0, i = 0, a = 0, c = (items - 3) / 2, ok = 1;
		ARStructItemList structItems;
		char            *buf = CPNULL;
		ARStatusList     status;
#if AR_CURRENT_API_VERSION >= 17
		unsigned int     exportOption = AR_EXPORT_DEFAULT;   /* TODO: support this as ars_Export() argument */
#endif
#if AR_EXPORT_VERSION >= 8L
		ARWorkflowLockStruct workflowLockStruct;
#endif
	  
		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);
		Zero(&structItems, 1, ARStructItemList);
#if AR_EXPORT_VERSION >= 8L
		Zero(&workflowLockStruct, 1, ARWorkflowLockStruct);
#endif
		RETVAL = &PL_sv_undef;
		if ( (items % 2 == 0) || (c < 1) ) {
			(void) ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_ARGS);
			ok = 0;
		} else {
			structItems.numItems = c;
			AMALLOCNN(structItems.structItemList, c, ARStructItemStruct);
			for (i = 0 ; i < c ; i++) {
				unsigned int et = 0;
				a  = i * 2 + 3;
				et = caseLookUpTypeNumber((TypeMapStruct *) 
							     StructItemTypeMap,
							   SvPV(ST(a), PL_na) 
							 );
				if(et == TYPEMAP_LAST) {
					(void) ARError_add(AR_RETURN_ERROR, AP_ERR_BAD_EXP);
					(void) ARError_add(AR_RETURN_ERROR, AP_ERR_CONTINUE,
						SvPV(ST(a), PL_na) );
					ok = 0;
				} else {
					structItems.structItemList[i].type = et;
					/* printf( "structItems.structItemList[i].type <%d>\n", structItems.structItemList[i].type ); */ /* _DEBUG_ */
					strncpy(structItems.structItemList[i].name,
						SvPV(ST(a+1), PL_na), 
						sizeof(ARNameType) );
					structItems.structItemList[i].name[sizeof(ARNameType)-1] = '\0';
					/* printf( "structItems.structItemList[i].name <%s>\n", structItems.structItemList[i].name ); */ /* _DEBUG_ */
				}
			}
		}
#if AR_EXPORT_VERSION >= 8L
			workflowLockStruct.lockType = 0;
			workflowLockStruct.lockKey[0] = '\0';
#endif

		if(ok) {
			ret = ARExport(ctrl, &structItems, displayTag, 
#if AR_EXPORT_VERSION >= 6
				       vuiType,
#endif
#if AR_CURRENT_API_VERSION >= 17
					   exportOption,	
#endif
#if AR_EXPORT_VERSION >= 8L
					   &workflowLockStruct,
#endif
				       &buf, &status);
#ifdef PROFILE
			((ars_ctrl *)ctrl)->queries++;
#endif
			if (! ARError(ret, status) ) {
				RETVAL = newSVpv(buf, 0);
			}
		} 
		if(buf) arsperl_FreeARTextString(buf);
		AP_FREE(structItems.structItemList);
	}
	OUTPUT:
	RETVAL

int
ars_Import(ctrl,importOption=AR_IMPORT_OPT_CREATE,importBuf,...)
	ARControlStruct *	ctrl
	char *			importBuf
	unsigned int            importOption
	CODE:
	{
		int               ret = 1, i = 0, a = 0, c = (items - 2) / 2, ok = 1;
		ARStructItemList *structItems = NULL;
		char             *objectModificationLogLabel = NULL;
		ARStatusList      status;

		(void) ARError_reset();	  
		Zero(&status, 1,ARStatusList);
		RETVAL = 0;
		if ((items-3) % 2) {
			(void) ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_ARGS);
			ok = 0;
		} else {
			if (c > 0) {
				AMALLOCNN(structItems, c, ARStructItemList);
				structItems->numItems = c;
				AMALLOCNN(structItems->structItemList, c,
				     ARStructItemStruct);
				for (i = 0; i < c; i++) {
					unsigned int et = 0;
					a  = i*2+3;

ARS.xs  view on Meta::CPAN

				changedSince,
#if AR_CURRENT_API_VERSION >= 17
				NULL,     /* &objPropList (undocumented by BMC) */
#endif
				&idList,
				&status);
#ifdef PROFILE
	  ((ars_ctrl *)ctrl)->queries++;
#endif
	  if(!ARError( ret, status)) {
	    for(i = 0 ; i < idList.numItems ; i++) {
		XPUSHs(sv_2mortal(newSViv(idList.internalIdList[i])));
	    }
	  }
	  FreeARInternalIdList(&idList, FALSE);
#else /* ars 2.x */
	  (void) ARError_reset();
	  (void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, "Not available in 2.x");
#endif
	}

void
ars_SetServerInfo(ctrl, ...)
	ARControlStruct *	ctrl
	PPCODE:
	{
		ARStatusList     status;
		ARServerInfoList serverInfo;
		int		 ret = 0, i = 0, count = 0;

		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);
		Zero(&serverInfo, 1, ARServerInfoList);

		if((items == 1) || ((items % 2) == 0)) { 
			(void) ARError_add(AR_RETURN_ERROR, 
					   AP_ERR_BAD_ARGS);
		} else {
			unsigned int infoType, j = 0;
			char         buf[256];

			serverInfo.numItems = (items - 1) / 2;
			serverInfo.serverInfoList = MALLOCNN(serverInfo.numItems * sizeof(ARServerInfoStruct));
			/* Zero(serverInfo.serverInfoList, 1, ARServerInfoStruct); # happens already in MALLOCNN */

			for(j = 0 ; j < serverInfo.numItems ; ++j) {
				i = 2 * j + 1;

				infoType = lookUpServerInfoTypeHint(SvIV(ST(i)));
				serverInfo.serverInfoList[j].operation = SvIV(ST(i));
				serverInfo.serverInfoList[j].value.dataType = infoType;

				switch(infoType) {
				case AR_DATA_TYPE_CHAR:
					serverInfo.serverInfoList[j].value.u.charVal = strdup(SvPV(ST(i+1), PL_na));
					break;
				case AR_DATA_TYPE_INTEGER:
					serverInfo.serverInfoList[j].value.u.intVal = SvIV(ST(i+1));
					break;
				default:
					sprintf( buf, "(%d) type = %d", serverInfo.serverInfoList[j].operation, serverInfo.serverInfoList[j].value.dataType );
					(void) ARError_add(AR_RETURN_ERROR, AP_ERR_INV_ARGS, 
						buf);
					FreeARServerInfoList(&serverInfo, FALSE);
					XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
					goto SetServerInfo_fail;
				}
			}
			ret = ARSetServerInfo(ctrl, &serverInfo, &status);
			FreeARServerInfoList(&serverInfo, FALSE);
			if(ARError(ret, status)) {
				XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
			} else {
				XPUSHs(sv_2mortal(newSViv(1))); /* OK */
			}
		}
	SetServerInfo_fail:;
	}

void
ars_GetServerInfo(ctrl, ...)
	ARControlStruct *	ctrl
	PPCODE:
	{
	  ARStatusList            status;
	  ARServerInfoRequestList requestList;
	  ARServerInfoList        serverInfo;
	  int                     ret = 0;
          int                     i  = 0;
          unsigned int            ui = 0, count = 0;
	  unsigned int            rlist[AR_MAX_SERVER_INFO_USED];

	  (void) ARError_reset();
	  Zero(&status, 1,ARStatusList);
	  Zero(&requestList, 1, ARServerInfoRequestList);
	  Zero(&serverInfo, 1, ARServerInfoList);
	  count = 0;
	  if(items == 1) { /* none specified.. fetch all */
	     for(i = 0; i < AR_MAX_SERVER_INFO_USED ; i++) {
	        /* we'll exclude ones that can't be retrieved to avoid errors */
	        switch(i+1) {
	           case AR_SERVER_INFO_DB_PASSWORD:
#if AR_CURRENT_API_VERSION < 17
	           case 332:
	           case 331:
	           case 330:
	           case 329:
	           case 328:
	           case 327:
	           case 326:
	           case 325:
#endif
	           break;
	        default:
	           rlist[count++] = i+1;
	        }
         }
	  }else if(items > AR_MAX_SERVER_INFO_USED + 1) {
	    ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_ARGS);
	  }else { /* user has asked for specific ones */
	     for(i = 1 ; i < items ; i++) {
	        rlist[count++] = SvIV(ST(i));
	     }
	  }
	  if(count > 0) {
	     requestList.numItems = count;
	     requestList.requestList = rlist;
	     ret = ARGetServerInfo(ctrl, &requestList, &serverInfo, &status);
#ifdef PROFILE
	     ((ars_ctrl *)ctrl)->queries++;
#endif
	     if(!ARError( ret, status)) {
	        for(ui = 0 ; ui < serverInfo.numItems ; ui++) {
		/* provided we have a mapping for the operation code, 
		 * push out it's translation. else push out the code itself
		 */
		   if(serverInfo.serverInfoList[ui].operation <= AR_MAX_SERVER_INFO_USED) {
		      /* printf( "%d %s: data type = %d\n", serverInfo.serverInfoList[ui].operation, ServerInfoMap[serverInfo.serverInfoList[ui].operation].name, serverInfo.serverInfoList[ui].value.dataType ); */
	  	      XPUSHs(sv_2mortal(newSVpv(ServerInfoMap[serverInfo.serverInfoList[ui].operation].name, 0)));
		   } else {
		      XPUSHs(sv_2mortal(newSViv(serverInfo.serverInfoList[ui].operation)));
		   }
		      XPUSHs(sv_2mortal(perl_ARValueStruct(ctrl,
			&(serverInfo.serverInfoList[ui].value))));
	        }
	     }
	    FreeARServerInfoList(&serverInfo, FALSE);
	  }
	}

HV *
ars_GetVUI(ctrl, schema, vuiId)
	ARControlStruct *	ctrl
	char *			schema
	ARInternalId		vuiId
	CODE:
	{
#if AR_EXPORT_VERSION >= 3
	  ARStatusList status;
	  ARNameType   vuiName;
	  ARPropList   dPropList;
	  char        *helpText = CPNULL;
	  ARTimestamp  timestamp;
	  ARAccessNameType   owner;
	  ARAccessNameType   lastChanged;
	  char        *changeDiary = CPNULL;
	  int          ret = 0;
	  ARDiaryList  diaryList;
	  ARPropList   objPropList;
# if AR_EXPORT_VERSION >= 6
	  unsigned int vuiType = 0;
	  ARLocaleType locale;
	  Zero(locale, 1, ARLocaleType);
# endif
	  RETVAL = newHV();
	  sv_2mortal( (SV*) RETVAL );
	  (void) ARError_reset();
	  Zero(&status, 1,ARStatusList);
	  Zero(vuiName, 1, ARNameType);
	  Zero(&dPropList, 1, ARPropList);
	  Zero(&objPropList, 1, ARPropList);
	  Zero(&timestamp, 1, ARTimestamp);
	  Zero(owner, 1, ARAccessNameType);
	  Zero(lastChanged, 1, ARAccessNameType);
	  ret = ARGetVUI(ctrl, schema, vuiId, vuiName,
# if AR_EXPORT_VERSION >= 6
			 locale, &vuiType,
# endif
			 &dPropList, &helpText, 
			 &timestamp, owner, lastChanged, &changeDiary,
#if AR_CURRENT_API_VERSION >= 17
			 &objPropList,
#endif
			 &status);
# ifdef PROFILE
	  ((ars_ctrl *)ctrl)->queries++;
# endif
	  if(!ARError( ret, status)) {

ARS.xs  view on Meta::CPAN

		rv += rev_ARDisplayInstanceList( ctrl, fieldDef, "displayInstanceList", &dInstanceList );

		if( hv_exists(fieldDef,"helpText",8) ){
			rv += strmakHVal( fieldDef, "helpText", &helpText ); 
		}
		if( hv_exists(fieldDef,"owner",5) ){
			rv += strcpyHVal( fieldDef, "owner", owner, AR_MAX_ACCESS_NAME_SIZE ); 
		}

		if( hv_exists(fieldDef,"changeDiary",11) ){
			rv += strmakHVal( fieldDef, "changeDiary", &changeDiary );
		}

		if( rv == 0 ){
			ret = ARCreateField( ctrl,
				schema,
				&fieldId,
				reservedIdOK,
				fieldName,
				&fieldMap,
				dataType,
				option,
				createMode,
#if AR_EXPORT_VERSION >= 9L
				fieldOption,
#endif
				defaultVal,
				&permissions,
				limit,
				&dInstanceList,
				helpText,
				owner,
				changeDiary,
#if AR_CURRENT_API_VERSION >= 17
				objPropList,
#endif
				&status );

			RETVAL = ARError(ret,status) ? 0 : fieldId;
		}else{ 
			ARError_add( AR_RETURN_ERROR, AP_ERR_PREREVFAIL);
			RETVAL = 0;
		}

	    if( helpText != NULL ){
			AP_FREE( helpText );
		}
	    if( changeDiary != NULL ){
			AP_FREE( changeDiary );
		}
		if( defaultVal != NULL ){
			FreeARValueStruct( defaultVal, TRUE );
		}
		FreeARPermissionList( &permissions, FALSE );
		if( limit != NULL ){
			FreeARFieldLimitStruct( limit, TRUE );
		}
		FreeARDisplayInstanceList( &dInstanceList, FALSE );
		/*
		FreeARStatusList( &status, FALSE );
		printf( "-- FreeARStatusList -- OK\n" );  // _DEBUG_
		*/
#else /* < 5.0 */
	  XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
	  (void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, 
			"ARSperl supports CreateField() only for ARSystem >= 5.0");
      RETVAL = AR_RETURN_ERROR;
#endif
	}
	OUTPUT:
	RETVAL



int
ars_SetField( ctrl, schema, fieldId, fieldDefRef )
	ARControlStruct *	ctrl
	ARNameType schema
	ARInternalId fieldId
	SV * fieldDefRef

	CODE:
	{
#if AR_EXPORT_VERSION >= 6L
		int ret = 0, rv = 0;
		ARNameType fieldName;
		char *fieldNamePtr = NULL;
		ARFieldMappingStruct *fieldMap = NULL;
		unsigned int *option = NULL;
		unsigned int *createMode = NULL;
#if AR_EXPORT_VERSION >= 9L
		unsigned int *fieldOption = NULL;
#endif
		ARValueStruct *defaultVal = NULL;
		ARPermissionList *permissions = NULL;
		ARFieldLimitStruct *limit = NULL;
		ARDisplayInstanceList *dInstanceList = NULL;
		char *helpText = NULL;
		ARAccessNameType owner;
		char *ownerPtr = NULL;
#if AR_EXPORT_VERSION >= 9L
		unsigned int	setFieldOptions = 0;
#endif
		char *changeDiary = NULL;
		ARPropList *objPropList = NULL;
		ARStatusList status;
		HV *fieldDef = NULL;
		SV **pSvTemp;
		char strTemp[STR_TEMP_SIZE+1];

		RETVAL = 0; /* assume error */
		(void) ARError_reset();
		Zero(fieldName, 1,ARNameType);
		Zero(owner, 1,ARAccessNameType);
		Zero(&status, 1,ARStatusList);

		if( SvROK(fieldDefRef) && SvTYPE(SvRV(fieldDefRef)) == SVt_PVHV ){
			fieldDef = (HV*) SvRV(fieldDefRef);
		}else{
			croak("usage: ars_SetField(...)");
		}

ARS.xs  view on Meta::CPAN

		}

		if( rv == 0 ){
			ret = ARSetField( ctrl,
				schema,
				fieldId,
				fieldNamePtr,
				fieldMap,
				option,
				createMode,
#if AR_EXPORT_VERSION >= 9L
				fieldOption,
#endif
				defaultVal,
				permissions,
				limit,
				dInstanceList,
				helpText,
				ownerPtr,
				changeDiary,
#if AR_EXPORT_VERSION >= 9L
				setFieldOptions,
#endif
#if AR_CURRENT_API_VERSION >= 17
				objPropList,
#endif
				&status );

			RETVAL = ARError(ret,status) ? 0 : fieldId;
		}else{ 
			ARError_add( AR_RETURN_ERROR, AP_ERR_PREREVFAIL);
			RETVAL = 0;
		}
		
	    if( createMode != NULL ){
			AP_FREE( createMode );
		}
	    if( option != NULL ){
			AP_FREE( option );
		}
	    if( helpText != NULL ){
			AP_FREE( helpText );
		}
	    if( changeDiary != NULL ){
			AP_FREE( changeDiary );
		}
		if( defaultVal != NULL ){
			FreeARValueStruct( defaultVal, TRUE );
		}
		if( permissions != NULL ){
			FreeARPermissionList( permissions, TRUE );
		}
		if( limit != NULL ){
			FreeARFieldLimitStruct( limit, TRUE );
		}
		if( dInstanceList != NULL ){
			FreeARDisplayInstanceList( dInstanceList, TRUE );
		}
		/*
		FreeARStatusList( &status, FALSE );
		printf( "-- FreeARStatusList -- OK\n" );  // _DEBUG_
		*/
#else /* < 5.0 */
	  XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
	  (void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, 
			"ARSperl supports SetField() only for ARSystem >= 5.0");
      RETVAL = AR_RETURN_ERROR;
#endif
	}
	OUTPUT:
	RETVAL



int
ars_CreateSchema( ctrl, schemaDefRef )
	ARControlStruct *	ctrl
	SV * schemaDefRef

	CODE:
	{
#if AR_EXPORT_VERSION >= 6L
		int ret = 0, rv = 0;
		ARNameType name;
		ARCompoundSchema compoundSchema;
		ARPermissionList groupList;
		ARInternalIdList admingrpList;
		AREntryListFieldList getListFields;
		ARSortList sortList;
		ARIndexList indexList;
#if AR_EXPORT_VERSION >= 8L
		ARArchiveInfoStruct *archiveInfo = NULL;
#endif
#if AR_EXPORT_VERSION >= 9L
		ARAuditInfoStruct *auditInfo = NULL;
#endif
		ARNameType defaultVui;
		char *helpText = NULL;
		ARAccessNameType owner;
		char *changeDiary = NULL;
		ARPropList *objPropList = NULL;
		char *objectModificationLogLabel = NULL;
		ARStatusList status;
		HV *schemaDef = NULL;
		SV **pSvTemp;
		/* char strTemp[STR_TEMP_SIZE+1]; */

		RETVAL = 0; /* assume error */
		(void) ARError_reset();
		Zero(name, 1,ARNameType);
		Zero(&compoundSchema, 1,ARCompoundSchema);
		Zero(&groupList, 1,ARPermissionList);
		Zero(&admingrpList, 1,ARInternalIdList);
		Zero(&getListFields, 1,AREntryListFieldList);
		Zero(&sortList, 1,ARSortList);
		Zero(&indexList, 1,ARIndexList);
		Zero(defaultVui, 1,ARNameType);
		Zero(owner, 1,ARAccessNameType);
		Zero(&status, 1,ARStatusList);

		if( SvROK(schemaDefRef) && SvTYPE(SvRV(schemaDefRef)) == SVt_PVHV ){

ARS.xs  view on Meta::CPAN

				&entryList.entryIdList[i],
				SvPV(*array_entry, PL_na)) != 0 ) {

				FreeAREntryIdListList(&entryList,FALSE);
				goto get_mentry_cleanup;
			}
		}
	} else {
		(void) ARError_add( AR_RETURN_ERROR, AP_ERR_BAD_EID );
		goto get_mentry_cleanup;
	}
	/*
	 * do API call
	 */
	ret = ARGetMultipleEntries(ctrl, schema, &entryList, &idList, 
				   &existList, &fieldList, &status);
#ifdef PROFILE
	((ars_ctrl *)ctrl)->queries++;
#endif
	if (ARError( ret, status)) {
		goto get_mentry_cleanup;
	}
	if(fieldList.numItems < 1) {
		goto get_mentry_cleanup;
	}
	/*
	 * build PERL copy of returned entries
	 */
	for (i=0; i < entryList.numItems; i++) {
		HV * fieldValue_hash;
		unsigned int field;
		char intstr[12];
		/*
		 * push entryID onto list
		 */
		if (entryList.entryIdList[i].numItems == 1) {
			/* only one entryId -- so just return its value to be compatible
			with ars 2 */
			XPUSHs(sv_2mortal(newSVpv(entryList.entryIdList[i].entryIdList[0], 0)));
		} else {
			/* more than one entry -- this must be a join schema. merge
			 * the list into a single entry-id to keep things
			 * consistent. */
			unsigned int   entry;
			char *joinId = (char *)NULL;
			char  joinSep[2] = {AR_ENTRY_ID_SEPARATOR, 0};
			for (entry=0; entry < entryList.entryIdList[i].numItems; entry++) {
				joinId = strappend(joinId, entryList.entryIdList[i].entryIdList[entry]);
				if(entry < entryList.entryIdList[i].numItems-1)
				joinId = strappend(joinId, joinSep);
			}
			XPUSHs(sv_2mortal(newSVpv(joinId, 0)));
		}
		/*
		 * push field/value hash reference onto list
		 */
		if ( existList.booleanList[i] ) {
			fieldValue_hash = newHV();
			/* sv_2mortal( (SV *)fieldValue_hash ); */
			for (field=0; field < fieldList.valueListList[i].numItems; field++) {
				sprintf(intstr,"%ld",fieldList.valueListList[i].fieldValueList[field].fieldId);
				hv_store( fieldValue_hash,
					intstr, strlen(intstr),
					perl_ARValueStruct(ctrl,&fieldList.valueListList[i].fieldValueList[field].value),
					0 );
			}
			XPUSHs( sv_2mortal( newRV_noinc((SV *)fieldValue_hash) ) );
		} else {
			XPUSHs(&PL_sv_undef);
		}
	}
	get_mentry_cleanup:;
	FreeARInternalIdList(&idList, FALSE);
	FreeAREntryIdListList(&entryList, FALSE);
	FreeARFieldValueListList(&fieldList, FALSE);
	FreeARBooleanList(&existList, FALSE);
	}


void
ars_GetListEntryWithFields(ctrl,schema,qualifier,maxRetrieve=0,firstRetrieve=0,...)
	ARControlStruct *       ctrl
	char *                  schema
	ARQualifierStruct *     qualifier
	unsigned int            firstRetrieve
	unsigned int            maxRetrieve
	PPCODE:
	{
	  ARStatusList     status;
	  unsigned int              c = (items - 5) / 2, i;
	  int              field_off = 5;
	  ARSortList       sortList;
	  AREntryListFieldValueList  entryFieldValueList;
	  int              ret = 0;
	  AREntryListFieldList getListFields, *getList = NULL;
	  AV              *getListFields_array;

	  (void) ARError_reset();
	  Zero(&status, 1, ARStatusList);
	  Zero(&sortList, 1, ARSortList);
	  Zero(&entryFieldValueList, 1, AREntryListFieldValueList);
	  Zero(&getListFields, 1, AREntryListFieldList);

	  sortList.sortList = NULL;
	  getListFields.fieldsList = NULL;
	  entryFieldValueList.entryList = NULL;
	  if ((items - 5) % 2) {
	    /* odd number of arguments, so argument after maxRetrieve is
	       optional getListFields (an array of hash refs) */
	    if ( SvROK(ST(field_off)) &&
	         (getListFields_array = (AV *)SvRV(ST(field_off))) &&
	         (SvTYPE(getListFields_array) == SVt_PVAV) ) {
	      getList = &getListFields;
	      getListFields.numItems = av_len(getListFields_array) + 1;
	      DBG( ("getListFields.numItems=%d\n", getListFields.numItems) );
	      /* Newz(777,getListFields.fieldsList, getListFields.numItems,AREntryListFieldStruct); */
	      getListFields.fieldsList = MALLOCNN( sizeof(AREntryListFieldStruct) * getListFields.numItems );
	      /* set query field list */
	      for (i=0; i<getListFields.numItems; i++) {
	        SV **array_entry;
	        /* get fieldID from array */

ARS.xs  view on Meta::CPAN

	        strncpy(getListFields.fieldsList[i].separator, " ", 2 );
	        DBG( ("i=%d, fieldId=%d, columnWidth=%d, separator=\"%s\"\n", i,
	             getListFields.fieldsList[i].fieldId,
	             getListFields.fieldsList[i].columnWidth,
	             getListFields.fieldsList[i].separator) );
	      }
	    } else {
	      (void) ARError_add( AR_RETURN_ERROR, AP_ERR_LFLDS_TYPE);
	      goto getlistentry_end;
	    }
	    /* increase the offset of the first sortList field by one */
	    field_off ++;
	  }
	  /* build sortList */
	  sortList.numItems = c;
	  /* Newz(777,sortList.sortList, c,  ARSortStruct); */
	  sortList.sortList = MALLOCNN( sizeof(ARSortStruct) * c );
	  for (i=0; i<c; i++) {
	    sortList.sortList[i].fieldId = SvIV(ST(i*2+field_off));
	    sortList.sortList[i].sortOrder = SvIV(ST(i*2+field_off+1));
	  }
	  ret = ARGetListEntryWithFields(ctrl, schema, qualifier, 
		getList, &sortList, 
#if AR_EXPORT_VERSION >= 6
		firstRetrieve,
#endif
		maxRetrieve, 
#if AR_EXPORT_VERSION >= 8L
                FALSE,
#endif
		&entryFieldValueList, NULL, &status);
#ifdef PROFILE
	  ((ars_ctrl *)ctrl)->queries++;
#endif
	  if (ARError( ret, status)) {
	    goto getlistentry_end;
	  }
	  for (i=0; i < entryFieldValueList.numItems; i++) {
	    HV * fieldValue_hash = newHV();
	    unsigned int field;
	    char intstr[12];
	    if (entryFieldValueList.entryList[i].entryId.numItems == 1) {
	      /* only one entryId -- so just return its value to be compatible
	         with ars 2 */
	      XPUSHs(sv_2mortal(newSVpv(entryFieldValueList.entryList[i].entryId.entryIdList[0], 0)));
	    } else {
	      /* more than one entry -- this must be a join schema. merge
	       * the list into a single entry-id to keep things
	       * consistent. */
	      unsigned int   entry;
	      char *joinId = (char *)NULL;
	      char  joinSep[2] = {AR_ENTRY_ID_SEPARATOR, 0};
	      for (entry=0; entry < entryFieldValueList.entryList[i].entryId.numItems; entry++) {
	        joinId = strappend(joinId, entryFieldValueList.entryList[i].entryId.entryIdList[entry]);
	        if(entry < entryFieldValueList.entryList[i].entryId.numItems-1)
	        joinId = strappend(joinId, joinSep);
	      }
	      XPUSHs(sv_2mortal(newSVpv(joinId, 0)));
	    }
	    for (field=0; field < entryFieldValueList.entryList[i].entryValues->numItems; field++) {
	      sprintf(intstr,"%ld",entryFieldValueList.entryList[i].entryValues->fieldValueList[field].fieldId);
	      hv_store( fieldValue_hash,
	                intstr, strlen(intstr),
	                perl_ARValueStruct(ctrl,&entryFieldValueList.entryList[i].entryValues->fieldValueList[field].value),
	                0 );
	    }
	    XPUSHs( sv_2mortal( newRV_noinc((SV *)fieldValue_hash) ) );
	  }
	  getlistentry_end:
	  FreeAREntryListFieldValueList( &entryFieldValueList,FALSE );
	  FreeARSortList( &sortList, FALSE );
	  FreeAREntryListFieldList( &getListFields, FALSE );
	}


void
ars_GetListEntryWithMultiSchemaFields(ctrl,schema,qualifier=NULL,maxRetrieve=0,firstRetrieve=0,fields=NULL,...)
	ARControlStruct *    ctrl
	SV *                 schema
	SV *                 qualifier
	unsigned int         firstRetrieve
	unsigned int         maxRetrieve
	SV *                 fields
	PPCODE:
	{
	ARStatusList     status;
#if AR_CURRENT_API_VERSION >= 14
#if AR_CURRENT_API_VERSION >= 17
	ARMultiSchemaFuncQueryFromList   queryFromList;
	ARMultiSchemaFieldFuncList       getListFields;
	ARMultiSchemaFieldFuncValueListList  entryFieldValueList;
	ARMultiSchemaFieldIdList         *groupBy = NULL;   /* TODO: support as function argument */
	ARMultiSchemaFuncQualifierStruct *having  = NULL;   /* TODO: support as function argument */
#else
	ARMultiSchemaQueryFromList       queryFromList;
	ARMultiSchemaFieldIdList         getListFields;
	ARMultiSchemaFieldValueListList  entryFieldValueList;
#endif
	ARMultiSchemaQualifierStruct     qualifierStruct;
	ARMultiSchemaSortList            sortList;
	unsigned int                     i;
	int                              i2, field_off = 6;
	int                              ret = 0, rv = 0;
	HV                               *hDummy;

	/* printf( "\n\n!!!! ars_GetListEntryWithMultiSchemaFields(): experimental implementation, not really working yet !!!!\n\n" ); */

	(void) ARError_reset();
#if AR_CURRENT_API_VERSION >= 17
	Zero( &queryFromList, 1, ARMultiSchemaFuncQueryFromList );
	Zero( &getListFields, 1, ARMultiSchemaFieldFuncList );
	Zero( &entryFieldValueList, 1, ARMultiSchemaFieldFuncValueListList );
#else
	Zero( &queryFromList, 1, ARMultiSchemaQueryFromList );
	Zero( &getListFields, 1, ARMultiSchemaFieldIdList );
	Zero( &entryFieldValueList, 1, ARMultiSchemaFieldValueListList );
#endif
	Zero( &qualifierStruct, 1, ARMultiSchemaQualifierStruct );
	Zero( &sortList, 1, ARMultiSchemaSortList );
	Zero( &status, 1, ARStatusList );

	hDummy = newHV();

	if( !( SvROK(schema) && SvTYPE(SvRV(schema)) == SVt_PVAV ) ){
		(void) ARError_add( AR_RETURN_ERROR, AP_ERR_GENERAL, "QueryFromList must be an ARRAY reference" );
		goto getlistentry_multischema_end;
	}
	hv_store( hDummy, "queryFromList", 13, newSVsv(schema), 0 );
#if AR_CURRENT_API_VERSION >= 17
	rv += rev_ARMultiSchemaFuncQueryFromList( ctrl, hDummy, "queryFromList", &queryFromList );
#else
	rv += rev_ARMultiSchemaQueryFromList( ctrl, hDummy, "queryFromList", &queryFromList );
#endif
	if( qualifier && SvOK(qualifier) ){
		if( !( SvROK(qualifier) && SvTYPE(SvRV(qualifier)) == SVt_PVHV ) ){
			(void) ARError_add( AR_RETURN_ERROR, AP_ERR_GENERAL, "Qualifier must be a HASH reference" );
			goto getlistentry_multischema_end;
		}
		hv_store( hDummy, "qualifierStruct", 15, newSVsv(qualifier), 0 );
		rv += rev_ARMultiSchemaQualifierStruct( ctrl, hDummy, "qualifierStruct", &qualifierStruct );
	}

	if( fields && SvOK(fields) ){
		if( !( SvROK(fields) && SvTYPE(SvRV(fields)) == SVt_PVAV ) ){
			(void) ARError_add( AR_RETURN_ERROR, AP_ERR_GENERAL, "GetListFields must be an ARRAY reference" );
			goto getlistentry_multischema_end;
		}
		hv_store( hDummy, "getListFields", 13, newSVsv(fields), 0 );
#if AR_CURRENT_API_VERSION >= 17
		rv += rev_ARMultiSchemaFieldFuncList( ctrl, hDummy, "getListFields", &getListFields );
#else
		rv += rev_ARMultiSchemaFieldIdList( ctrl, hDummy, "getListFields", &getListFields );
#endif
	}

	if( items > field_off ){
		int arg, c = (items - field_off) / 2;
		if( (items - field_off) % 2 ){
			(void) ARError_add( AR_RETURN_ERROR, AP_ERR_GENERAL, "Odd number of SortList arguments" );
			goto getlistentry_multischema_end;
		}

		sortList.numItems = c;
		sortList.listPtr = MALLOCNN( sizeof(ARMultiSchemaSortStruct) * c );
		for( i2 = 0; i2 < c; ++i2 ){
			arg = field_off + i2 * 2;
			hv_store( hDummy, "_", 1, newSVsv(ST(arg)), 0 );
			rv += rev_ARMultiSchemaFieldIdStruct( ctrl, hDummy, "_", &(sortList.listPtr[i2].fieldId) );
			sortList.listPtr[i2].sortOrder = SvUV(ST(arg+1));
		}
	}


	if( rv != 0 ){
		ARError_add( AR_RETURN_ERROR, AP_ERR_PREREVFAIL );
		goto getlistentry_multischema_end;
	}

	ret = ARGetListEntryWithMultiSchemaFields( ctrl,
		&queryFromList,
		&getListFields,
		&qualifierStruct, 
		&sortList, 
		firstRetrieve,
		maxRetrieve, 
		FALSE,
#if AR_CURRENT_API_VERSION >= 17
		groupBy,
		having,
#endif
		&entryFieldValueList,
		NULL,                  /* TODO: numMatches */
		&status );
#ifdef PROFILE
	((ars_ctrl *)ctrl)->queries++;
#endif
	if( ARError( ret, status) ){
		goto getlistentry_multischema_end;
	}
#if AR_CURRENT_API_VERSION >= 17
	for( i = 0; i < entryFieldValueList.numItems; ++i ){
		HV * fieldValue_hash = newHV();
		unsigned int field;
		char keyStr[AR_MAX_NAME_SIZE + 1 + 12 + 1 + 12 + 1];

		for( field = 0; field < entryFieldValueList.listPtr[i].numItems; ++field ){
			ARMultiSchemaFieldFuncValueStruct *valPtr = &(entryFieldValueList.listPtr[i].listPtr[field]);
			sprintf( keyStr, "%s.%ld.%ld", valPtr->fieldId.queryFromAlias, valPtr->fieldId.fieldId, valPtr->fieldId.funcId );
			hv_store( fieldValue_hash,
				keyStr, strlen(keyStr),
				perl_ARValueStruct(ctrl, &(valPtr->value)),
				0 );
		}
		XPUSHs( sv_2mortal( newRV_noinc((SV *)fieldValue_hash) ) );
	}
#else
	for( i = 0; i < entryFieldValueList.numItems; ++i ){
		HV * fieldValue_hash = newHV();
		unsigned int field;
		char keyStr[AR_MAX_NAME_SIZE + 1 + 12 + 1];

		for( field = 0; field < entryFieldValueList.listPtr[i].numItems; ++field ){
			ARMultiSchemaFieldValueStruct *valPtr = &(entryFieldValueList.listPtr[i].listPtr[field]);
			sprintf( keyStr, "%s.%ld", valPtr->fieldId.queryFromAlias, valPtr->fieldId.fieldId );
			hv_store( fieldValue_hash,
				keyStr, strlen(keyStr),
				perl_ARValueStruct(ctrl, &(valPtr->value)),
				0 );
		}
		XPUSHs( sv_2mortal( newRV_noinc((SV *)fieldValue_hash) ) );
	}
#endif

	getlistentry_multischema_end:
	hv_undef( hDummy );
#if AR_CURRENT_API_VERSION >= 17
	FreeARMultiSchemaFieldFuncList( &getListFields, FALSE );
	FreeARMultiSchemaFieldFuncValueListList( &entryFieldValueList, FALSE );
#else
	FreeARMultiSchemaFieldIdList( &getListFields, FALSE );
	FreeARMultiSchemaFieldValueListList( &entryFieldValueList, FALSE );
#endif
	FreeARMultiSchemaSortList( &sortList, FALSE );
#else	/* prior to ARS 7.5 */
	(void) ARError_reset();
	Zero(&status, 1, ARStatusList);
	(void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED,
	"ars_GetListEntryWithMultiSchemaFields() is only available in ARS >= 7.5");
#endif
	}



void
ars_SetLogging( ctrl, logTypeMask_arg, ...)
	ARControlStruct *	ctrl
	unsigned long     logTypeMask_arg
	PPCODE:
	{
#if AR_EXPORT_VERSION >= 5
		ARStatusList     status;
#if AR_CURRENT_API_VERSION >= 14
		ARULong32        whereToWriteMask = AR_WRITE_TO_STATUS_LIST;
		ARULong32        logTypeMask      = logTypeMask_arg;
#else
		unsigned long    whereToWriteMask = AR_WRITE_TO_STATUS_LIST;
		unsigned long    logTypeMask      = logTypeMask_arg;
#endif
		int	             ret;
		FILE             *logFilePtr = NULL;

		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);

		logFilePtr = get_logging_file_ptr();
		/* printf( "GET logging_file_ptr = %p\n", logFilePtr ); */

		if( items > 2 && logTypeMask != 0 ){
			char *fileName;
			STRLEN len;
			fileName = SvPV(ST(2),len);

			if( logFilePtr != NULL ){
				fclose( logFilePtr );
				logFilePtr = NULL;
			}

			whereToWriteMask = AR_WRITE_TO_FILE;
			logFilePtr = fopen( fileName, "a" );

			if( logFilePtr == NULL ){
				char buf[2048];
				sprintf( buf, "Cannot open file: %s", fileName );
				(void) ARError_add( AR_RETURN_ERROR, AP_ERR_INV_ARGS, buf);
				XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
				goto SetLogging_fail;
			}
			set_logging_file_ptr( logFilePtr );
			/* printf( "SET logging_file_ptr = %p\n", logFilePtr ); */
		}

		ret = ARSetLogging( ctrl, logTypeMask, whereToWriteMask, logFilePtr, &status );

		if( logTypeMask == 0 && logFilePtr != NULL ){
			fclose( logFilePtr );
			set_logging_file_ptr( NULL );
		}

		if(ARError(ret, status)) {
			XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
		} else {
			XPUSHs(sv_2mortal(newSViv(1))); /* OK */
		}
	SetLogging_fail:;
#else /* < 4.5 */
	  XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
	  (void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, 
			"SetLogging() is only available in ARSystem >= 4.5");
#endif
	}


void
ars_SetSessionConfiguration( ctrl, variableId, value )
	ARControlStruct *	ctrl
	unsigned int      variableId
	long              value
	PPCODE:
	{
#if AR_EXPORT_VERSION >= 6
		ARStatusList     status;
		ARValueStruct    variableValue;
		int	             ret;
		char             numToCharBuf[32];

		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);

		variableValue.dataType = AR_DATA_TYPE_INTEGER;
		variableValue.u.intVal = value;
		
		if (variableId == 12 || variableId == 13)
		{
			// just a quick and dirty solution because those variables need to be characters
			sprintf(numToCharBuf, "%ld", value);
			variableValue.dataType = AR_DATA_TYPE_CHAR;
			variableValue.u.charVal = numToCharBuf;
		}

		ret = ARSetSessionConfiguration( ctrl, variableId, &variableValue, &status );

		if(ARError(ret, status)) {
			XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
		} else {
			XPUSHs(sv_2mortal(newSViv(1))); /* OK */
		}
#else /* < 5.0 */
	  XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
	  (void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, 
			"SetSessionConfiguration() is only available in ARSystem >= 5.0");
#endif
	}


void
ars_SetImpersonatedUser( ctrl, impersonatedUser )
	ARControlStruct *	ctrl
	ARAccessNameType  impersonatedUser
	PPCODE:
	{
#if AR_EXPORT_VERSION >= 9
		ARStatusList     status;
		int	             ret;

		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);

		if( strcmp("",impersonatedUser) == 0 ){
			ret = ARSetImpersonatedUser( ctrl, NULL, &status );
		}else{
			ret = ARSetImpersonatedUser( ctrl, impersonatedUser, &status );
		}

		if(ARError(ret, status)) {
			XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
		} else {
			XPUSHs(sv_2mortal(newSViv(1))); /* OK */
		}
#else /* < 7.0 */
		XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
		(void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, 
			  "SetImpersonatedUser() is only available in ARSystem >= 7.0");
#endif
	}





void
ars_BeginBulkEntryTransaction( ctrl )
	ARControlStruct *	ctrl
	PPCODE:
	{
#if AR_CURRENT_API_VERSION >= 11

ARS.xs  view on Meta::CPAN

		ARValueStruct    varValue;
		Zero(&status, 1, ARStatusList);
		Zero(&varValue, 1, ARValueStruct);
		
		ret = ARGetSessionConfiguration(ctrl, variableId, &varValue, &status);
		
		if( !ARError(ret, status) ) {
			RETVAL = perl_ARValueStruct(ctrl, &varValue);
		}
		else
		{
			RETVAL = &PL_sv_undef;
		}
		FreeARValueStruct(&varValue, FALSE);
#else /* < 5.0 */
	  XPUSHs(sv_2mortal(newSViv(0))); /* ERR */
	  (void) ARError_add( AR_RETURN_ERROR, AP_ERR_DEPRECATED, 
			"GetSessionConfiguration() is only available in ARSystem >= 5.0");
#endif
	}
	OUTPUT:
	RETVAL

#
# Destructors for Blessed C structures
#

MODULE = ARS		PACKAGE = ARControlStructPtr

void
DESTROY(ctrl)
	ARControlStruct *	ctrl
	CODE:
	{
		ARStatusList status;
		int rv = 0;

		(void) ARError_reset();
		Zero(&status, 1, ARStatusList);
		DBG( ("control struct destructor\n") );
# if AR_EXPORT_VERSION >= 4
		rv = ARTermination(ctrl, &status);
# else
		rv = ARTermination(&status);
# endif /* AR_EXPORT_VERSION */
		(void) ARError(rv, status);
#ifdef PROFILE
		AP_FREE(ctrl);
#else
		safefree(ctrl);
#endif
	}


char *
field_cache_key(ctrl)
	ARControlStruct *	ctrl
	CODE:
	{
	  char     server_tag[100];
	  sprintf( server_tag, "%s:%p", ctrl->server, ctrl );
	  RETVAL = server_tag;
	}
	OUTPUT:
	RETVAL


MODULE = ARS		PACKAGE = ARQualifierStructPtr

void
DESTROY(qual)
	ARQualifierStruct *	qual
	CODE:
	{
		DBG( ("arqualifierstruct destructor (%p)\n", qual) );
		FreeARQualifierStruct(qual, FALSE);
		AP_FREE(qual);
	}



( run in 1.579 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )