Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief UBF library
0003  *   The emulator of UBF library
0004  *   Enduro Execution Library
0005  *   Implementation of Bupdate, Bconcat
0006  *
0007  * @file fmerge.c
0008  */
0009 /* -----------------------------------------------------------------------------
0010  * Enduro/X Middleware Platform for Distributed Transaction Processing
0011  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0012  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0013  * This software is released under one of the following licenses:
0014  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0015  * See LICENSE file for full text.
0016  * -----------------------------------------------------------------------------
0017  * AGPL license:
0018  *
0019  * This program is free software; you can redistribute it and/or modify it under
0020  * the terms of the GNU Affero General Public License, version 3 as published
0021  * by the Free Software Foundation;
0022  *
0023  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0024  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0025  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0026  * for more details.
0027  *
0028  * You should have received a copy of the GNU Affero General Public License along 
0029  * with this program; if not, write to the Free Software Foundation, Inc.,
0030  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0031  *
0032  * -----------------------------------------------------------------------------
0033  * A commercial use license is available from Mavimax, Ltd
0034  * contact@mavimax.com
0035  * -----------------------------------------------------------------------------
0036  */
0037 
0038 /*---------------------------Includes-----------------------------------*/
0039 #include <string.h>
0040 #include <stdio.h>
0041 #include <stdlib.h>
0042 #include <memory.h>
0043 
0044 #include <ubf.h>
0045 #include <ubf_int.h>    /* Internal headers for UBF... */
0046 #include <fdatatype.h>
0047 #include <ferror.h>
0048 #include <fieldtable.h>
0049 #include <ndrstandard.h>
0050 #include <ndebug.h>
0051 #include <cf.h>
0052 /*---------------------------Externs------------------------------------*/
0053 /*---------------------------Macros-------------------------------------*/
0054 /*---------------------------Enums--------------------------------------*/
0055 /*---------------------------Typedefs-----------------------------------*/
0056 /*---------------------------Globals------------------------------------*/
0057 /*---------------------------Statics------------------------------------*/
0058 /*---------------------------Prototypes---------------------------------*/
0059 
0060 
0061 /**
0062  * We will use temp buffer here.
0063  * This is not the most optimal version. But we will re-use existing components.
0064  * @param p_ub_dst
0065  * @param p_ub_src
0066  * @return
0067  */
0068 expublic int ndrx_Bupdate (UBFH *p_ub_dst, UBFH *p_ub_src)
0069 {
0070     int ret=EXSUCCEED;
0071     UBF_header_t *hdr = (UBF_header_t *)p_ub_dst;
0072     char *p_fld;
0073     BFLDID bfldid = BFIRSTFLDID;
0074     BFLDOCC occ = 0;
0075     BFLDLEN len=0;
0076     Bnext_state_t state;
0077     int nxt_stat;
0078     Bfld_loc_info_t chg_state;
0079     memset(&chg_state, 0, sizeof(chg_state));
0080     memset(&state, 0, sizeof(state));
0081     chg_state.last_checked = &hdr->bfldid;
0082             
0083     while(EXSUCCEED==ret &&
0084         1==(nxt_stat=ndrx_Bnext(&state, p_ub_src, &bfldid, &occ, NULL, &len, &p_fld)))
0085     {
0086         /*
0087          * Update the occurrence in target buffer.
0088          */
0089         if (EXSUCCEED!=(ret=ndrx_Bchg(p_ub_dst, bfldid, occ, p_fld, len, &chg_state, EXFALSE)))
0090         {
0091             UBF_LOG(log_debug, "Failed to set %s[%d]", 
0092                                 ndrx_Bfname_int(bfldid), occ);
0093         }
0094     }
0095 
0096     if (EXFAIL==nxt_stat)
0097         ret=EXFAIL;
0098 
0099     return ret;
0100 }
0101 
0102 /**
0103  * Contact two buffers.
0104  * @param p_ub_dst
0105  * @param p_ub_src
0106  * @return
0107  */
0108 expublic int ndrx_Bconcat (UBFH *p_ub_dst, UBFH *p_ub_src)
0109 {
0110     int ret=EXSUCCEED;
0111     UBF_header_t *hdr = (UBF_header_t *)p_ub_dst;
0112     char *p_fld;
0113     BFLDID bfldid = BFIRSTFLDID;
0114     BFLDOCC occ = 0;
0115     BFLDLEN len=0;
0116     Bnext_state_t state;
0117     int nxt_stat;
0118     Bfld_loc_info_t add_state;
0119 
0120    
0121     memset(&add_state, 0, sizeof(add_state));
0122     add_state.last_checked = &hdr->bfldid;
0123 
0124     memset(&state, 0, sizeof(state));
0125 
0126     while(EXSUCCEED==ret &&
0127                1==(nxt_stat=ndrx_Bnext(&state, p_ub_src, &bfldid, &occ, NULL, &len, &p_fld)))
0128     {
0129         /*
0130          * Add new occurrences to the buffer.
0131      * TODO: might want to optimise if adding same field... with next_fld
0132          */
0133         if (EXSUCCEED!=(ret=ndrx_Badd(p_ub_dst, bfldid, p_fld, len, 
0134         &add_state, NULL)))
0135         {
0136             UBF_LOG(log_debug, "Failed to set %s[%d]",
0137                                                 ndrx_Bfname_int(bfldid), occ);
0138         }
0139     }
0140 
0141     if (EXFAIL==nxt_stat)
0142         ret=EXFAIL;
0143 
0144     return ret;
0145 }
0146 
0147 /**
0148  * Join two buffers, update only existing fields in dest, remove missing fields
0149  * @param dest - dest buffer (being modified)
0150  * @param src - src buffer (not modified)
0151  * @return SUCCEED/FAIL
0152  */
0153 expublic int ndrx_Bjoin (UBFH *dest, UBFH *src)
0154 {
0155     int ret=EXSUCCEED;
0156     UBF_header_t *hdr = (UBF_header_t *)dest;
0157     char *p_fld;
0158     BFLDID bfldid = BFIRSTFLDID;
0159     BFLDOCC occ = 0;
0160     BFLDLEN len=0;
0161     Bnext_state_t state;
0162     int nxt_stat;
0163     Bfld_loc_info_t chg_state;
0164     memset(&chg_state, 0, sizeof(chg_state));
0165     memset(&state, 0, sizeof(state));
0166     chg_state.last_checked = &hdr->bfldid;
0167 
0168     while(EXSUCCEED==ret &&
0169         1==(nxt_stat=ndrx_Bnext(&state, src, &bfldid, &occ, NULL, &len, &p_fld)))
0170     {
0171         /*
0172          * Update the occurrence in target buffer.
0173          */
0174         if (EXSUCCEED!=ndrx_Bchg(dest, bfldid, occ, p_fld, len, &chg_state, EXTRUE))
0175         {
0176             UBF_LOG(log_debug, "Failed to set %s[%d]", 
0177                                 ndrx_Bfname_int(bfldid), occ);
0178             EXFAIL_OUT(ret);
0179         }
0180     }
0181 
0182     if (EXFAIL==nxt_stat)
0183     {
0184         EXFAIL_OUT(ret);
0185     }
0186     UBF_LOG(log_debug, "Delete fields from destination buffer which not have in source buffer");
0187 repeat:
0188     memset(&state, 0, sizeof(state));
0189     bfldid= BFIRSTFLDID;
0190 
0191     while(EXSUCCEED==ret &&
0192         1==(nxt_stat=ndrx_Bnext(&state, dest, &bfldid, &occ, NULL, &len, NULL)))
0193     {
0194         /*
0195          * Delete fields from destination buffer which not have in source buffer
0196          */
0197         if (EXTRUE != _Bpres(src, bfldid, occ))
0198         {
0199             if (EXSUCCEED!=(ret=Bdel(dest, bfldid, occ)))
0200             {
0201                 UBF_LOG(log_debug, "Failed to delete %s[%d]", 
0202                                 ndrx_Bfname_int(bfldid), occ);
0203                 EXFAIL_OUT(ret);
0204             }
0205             goto repeat;
0206         }
0207 
0208     }
0209     
0210 out:
0211     return ret;
0212 }
0213 
0214 /**
0215  * Outer join two buffers, update existing, do not remove non-existing fields
0216  * @param dest - dest buffer (being modified)
0217  * @param src - src buffer (not modified)
0218  * @return SUCCEED/FAIL
0219  */
0220 expublic int ndrx_Bojoin (UBFH *dest, UBFH *src)
0221 {
0222     int ret=EXSUCCEED;
0223     UBF_header_t *hdr = (UBF_header_t *)dest;
0224     char *p_fld;
0225     BFLDID bfldid = BFIRSTFLDID;
0226     BFLDOCC occ = 0;
0227     BFLDLEN len=0;
0228     Bnext_state_t state;
0229     int nxt_stat;
0230     Bfld_loc_info_t chg_state;
0231     memset(&chg_state, 0, sizeof(chg_state));
0232     memset(&state, 0, sizeof(state));
0233     chg_state.last_checked = &hdr->bfldid;
0234 
0235     while(EXSUCCEED==ret &&
0236         1==(nxt_stat=ndrx_Bnext(&state, src, &bfldid, &occ, NULL, &len, &p_fld)))
0237     {
0238         /*
0239          * Update the occurrence in target buffer.
0240          */
0241         if (EXSUCCEED!=ndrx_Bchg(dest, bfldid, occ, p_fld, len, &chg_state, EXTRUE))
0242         {
0243             UBF_LOG(log_debug, "Failed to set %s[%d]", 
0244                                 ndrx_Bfname_int(bfldid), occ);
0245             EXFAIL_OUT(ret);
0246         }
0247     }
0248 
0249     if (EXFAIL==nxt_stat)
0250     {
0251         ret=EXFAIL;
0252     }
0253 
0254 out:
0255     return ret;
0256 }
0257 /* vim: set ts=4 sw=4 et smartindent: */