Esempio n. 1
0
static EdiField mdbReadField(Edi *edi, cchar *tableName, cchar *key, cchar *fieldName)
{
    Mdb         *mdb;
    MdbTable    *table;
    MdbCol      *col;
    MdbRow      *row;
    EdiField    field, err;
    int         r;

    mdb = (Mdb*) edi;
    lock(mdb);
    err.valid = 0;
    if ((table = lookupTable(mdb, tableName)) == 0) {
        unlock(mdb);
        return err;
    }
    if ((col = lookupColumn(table, fieldName)) == 0) {
        unlock(mdb);
        return err;
    }
    if ((r = lookupRow(table, key)) < 0) {
        unlock(mdb);
        return err;
    }
    row = mprGetItem(table->rows, r);
    field = makeFieldFromRow(row, col);
    unlock(mdb);
    return field;
}
Esempio n. 2
0
/*
    Lookup a property by name. There are 7 kinds of lookups:
         prop, @att, [prop], *, @*, .name, .@name
 */
static EjsObj *getXmlListPropertyByName(Ejs *ejs, EjsXML *list, EjsName qname)
{
    EjsXML      *result, *subList, *item;
    int         nextItem;

    /*
        Get the n'th item in the list
     */
    if (isdigit((uchar) qname.name->value[0]) && allDigitsForXmlList(qname.name)) {
        return mprGetItem(list->elements, ejsAtoi(ejs, qname.name, 10));
    }

    result = ejsCreateXMLList(ejs, list, qname);

    /*
        Build a list of all the elements that themselves have a property qname
     */
    for (nextItem = 0; (item = mprGetNextItem(list->elements, &nextItem)) != 0; ) {
        if (item->kind == EJS_XML_ELEMENT) {
            subList = ejsGetPropertyByName(ejs, (EjsObj*) item, qname);
            assure(ejsIsXML(ejs, subList));
            ejsAppendToXML(ejs, result, subList);

        } else {
            //  TODO - do we ever get a list in a list?
            assure(0);
        }
    }
    return (EjsObj*) result;
}
Esempio n. 3
0
static int deleteXmlListPropertyByName(Ejs *ejs, EjsXML *list, EjsName qname)
{
    EjsXML      *elt;
    int         index, next;

    if (isdigit((uchar) qname.name->value[0]) && allDigitsForXmlList(qname.name)) {
        index = ejsAtoi(ejs, qname.name, 10);

        elt = (EjsXML*) mprGetItem(list->elements, index);
        if (elt) {
            if (elt->parent) {
                if (elt->kind == EJS_XML_ATTRIBUTE) {
                    ejsDeletePropertyByName(ejs, (EjsObj*) elt->parent, elt->qname);
                } else {
                    //  TODO - let q be the property of parent where parent[q] == x[i]
                    mprRemoveItem(elt->parent->elements, elt);
                    elt->parent = 0;
                }
            }
        }
        //  Spec says return true even if index is out of range. We return 0 for true and < 0 for false.
        //  TODO - should ejs throw?
        return 0;
    }

    for (next = 0; (elt = mprGetNextItem(list->elements, &next)) != 0; ) {
        if (elt->kind == EJS_XML_ELEMENT /* && elt->parent */) {
            ejsDeletePropertyByName(ejs, (EjsObj*) elt /* TODO was elt->parent */, qname);
        }
    }
    return 0;
}
Esempio n. 4
0
static EdiRec *mdbReadRec(Edi *edi, cchar *tableName, cchar *key)
{
    Mdb         *mdb;
    MdbTable    *table;
    MdbRow      *row;
    EdiRec      *rec;
    int         r;

    mdb = (Mdb*) edi;
    rec = 0;

    lock(mdb);
    if ((table = lookupTable(mdb, tableName)) == 0) {
        unlock(mdb);
        return 0;
    }
    if ((r = lookupRow(table, key)) < 0) {
        unlock(mdb);
        return 0;
    }
    if ((row = mprGetItem(table->rows, r)) != 0) {
        rec = createRecFromRow(edi, row);
    }
    unlock(mdb);
    return rec;
}
Esempio n. 5
0
int maInsertAlias(MaHost *host, MaAlias *newAlias)
{
    MaAlias     *alias, *old;
    int         rc, next, index;

    if (mprGetParent(host->aliases) == host->parent) {
        host->aliases = mprDupList(host, host->parent->aliases);
    }

    /*
     *  Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc. But we sort redirects with
     *  status codes first.
     */
    for (next = 0; (alias = mprGetNextItem(host->aliases, &next)) != 0; ) {
        rc = strcmp(newAlias->prefix, alias->prefix);
        if (rc == 0) {
            index = mprLookupItem(host->aliases, alias);
            old = (MaAlias*) mprGetItem(host->aliases, index);
            mprRemoveItem(host->aliases, alias);
            mprInsertItemAtPos(host->aliases, next - 1, newAlias);
            return 0;
            
        } else if (rc > 0) {
            if (newAlias->redirectCode >= alias->redirectCode) {
                mprInsertItemAtPos(host->aliases, next - 1, newAlias);
                return 0;
            }
        }
    }
    mprAddItem(host->aliases, newAlias);
    return 0;
}
Esempio n. 6
0
/*
    Deep compare
 */
static bool deepCompare(EjsXML *lhs, EjsXML *rhs)
{
    EjsXML      *l, *r;
    int         i;

    if (lhs == rhs) {
        return 1;
    }
    //  TODO - must compare all the namespaces?
    if (lhs->kind != rhs->kind) {
        return 0;

    } else  if (lhs->qname.name != rhs->qname.name) {
        return 0;

    } else if (mprGetListLength(lhs->attributes) != mprGetListLength(rhs->attributes)) {
        //  TODO - must compare all the attributes
        return 0;

    } else if (mprGetListLength(lhs->elements) != mprGetListLength(rhs->elements)) {
        //  TODO - must compare all the children
        return 0;

    } else if (lhs->value != rhs->value) {
        return 0;

    } else {
        for (i = 0; i < mprGetListLength(lhs->elements); i++) {
            l = mprGetItem(lhs->elements, i);
            r = mprGetItem(rhs->elements, i);
            if (! deepCompare(l, r)) {
                return 0;
            }
        }
    }
    return 1;
}
Esempio n. 7
0
static void serviceIO(MprWaitService *ws, struct epoll_event *events, int count)
{
    MprWaitHandler      *wp;
    struct epoll_event  *ev;
    int                 fd, i, mask;

    lock(ws);
    for (i = 0; i < count; i++) {
        ev = &events[i];
        fd = ev->data.fd;
        if (fd == ws->breakFd[MPR_READ_PIPE]) {
            char buf[16];
            if (read(fd, buf, sizeof(buf)) < 0) {}
            continue;
        }
        if (fd < 0 || (wp = mprGetItem(ws->handlerMap, fd)) == 0) {
            /*
                This can happen if a writable event has been triggered (e.g. MprCmd command stdin pipe) and the pipe is closed.
                This thread may have waked from kevent before the pipe is closed and the wait handler removed from the map.

                mprLog("error mpr event", 0, "fd not in handler map. fd %d", fd);
             */
            continue;
        }
        mask = 0;
        if (ev->events & (EPOLLIN | EPOLLHUP | EPOLLERR)) {
            mask |= MPR_READABLE;
        }
        if (ev->events & (EPOLLOUT | EPOLLHUP)) {
            mask |= MPR_WRITABLE;
        }
        wp->presentMask = mask & wp->desiredMask;
        if (wp->presentMask) {
            if (wp->flags & MPR_WAIT_IMMEDIATE) {
                (wp->proc)(wp->handlerData, NULL);
            } else {
                /*
                    Suppress further events while this event is being serviced. User must re-enable.
                 */
                mprNotifyOn(wp, 0);
                mprQueueIOEvent(wp);
            }
        }
    }
    unlock(ws);
}
Esempio n. 8
0
static MprList *mdbGetTables(Edi *edi)
{
    Mdb         *mdb;
    MprList     *list;
    MdbTable     *table;
    int         tid, ntables;

    mdb = (Mdb*) edi;
    lock(mdb);
    list = mprCreateList(-1, 0);
    ntables = mprGetListLength(mdb->tables);
    for (tid = 0; tid < ntables; tid++) {
        table = mprGetItem(mdb->tables, tid);
        mprAddItem(list, table->name);
    }
    unlock(mdb);
    return list;
}
Esempio n. 9
0
/*
    Return true if the join is successful
 */
static int reapJoins(Ejs *ejs, EjsObj *workers)
{
    EjsWorker   *worker;
    EjsArray    *set;
    int         i, completed, joined, count;

    lock(ejs);
    completed = 0;
    joined = 0;

    if (workers == 0 || ejsIs(ejs, workers, Null)) {
        /* Join all */
        count = mprGetListLength(ejs->workers);
        for (i = 0; i < count; i++) {
            worker = mprGetItem(ejs->workers, i);
            if (worker->state >= EJS_WORKER_COMPLETE) {
                completed++;
            }
        }
        if (completed == count) {
            joined = 1;
        }
    } else if (ejsIs(ejs, workers, Array)) {
        /* Join a set */
        set = (EjsArray*) workers;
        for (i = 0; i < set->length; i++) {
            worker = (EjsWorker*) set->data[i];
            if (worker->state >= EJS_WORKER_COMPLETE) {
                completed++;
            }
        }
        if (completed == set->length) {
            joined = 1;
        }
    } else if (TYPE(workers) == ESV(Worker)) {
        /* Join one worker */
        worker = (EjsWorker*) workers;
        if (worker->state >= EJS_WORKER_COMPLETE) {
            joined = 1;
        }
    }
    unlock(ejs);
    return joined;
}
Esempio n. 10
0
static int reapJoins(Ejs *ejs, EjsVar *workers)
{
    EjsWorker   *worker;
    EjsArray    *set;
    int         i, completed;

    lock(ejs);
    if (workers == 0 || workers == ejs->nullValue) {
        completed = 0;
        for (i = 0; i < mprGetListCount(ejs->workers); i++) {
            worker = mprGetItem(ejs->workers, i);
            if (worker->state >= EJS_WORKER_COMPLETE) {
                completed++;
            }
        }
        if (completed == mprGetListCount(ejs->workers)) {
            unlock(ejs);
            return 1;
        }
    } else if (ejsIsArray(workers)) {
        set = (EjsArray*) workers;
        for (i = 0; i < set->length; i++) {
            worker = (EjsWorker*) set->data[i];
            if (worker->state < EJS_WORKER_COMPLETE) {
                break;
            }
        }
        if (i >= set->length) {
            unlock(ejs);
            return 1;
        }
    } else if (workers->type == ejs->workerType) {
        worker = (EjsWorker*) workers;
        if (worker->state >= EJS_WORKER_COMPLETE) {
            unlock(ejs);
            return 1;
        }
    }
    unlock(ejs);
    return 0;
}
Esempio n. 11
0
/*
    Function to iterate and return the next element value.
    NOTE: this is not a method of Xml. Rather, it is a callback function for Iterator
 */
static EjsObj *nextXmlValue(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv)
{
    EjsXML      *xml, *vp;

    xml = (EjsXML*) ip->target;
    if (!ejsIsXML(ejs, xml)) {
        ejsThrowReferenceError(ejs, "Wrong type");
        return 0;
    }

    for (; ip->index < mprGetListLength(xml->elements); ip->index++) {
        vp = (EjsXML*) mprGetItem(xml->elements, ip->index);
        if (vp == 0) {
            continue;
        }
        ip->index++;
        return (EjsObj*) vp;
    }
    ejsThrowStopIteration(ejs);
    return 0;
}
Esempio n. 12
0
/*
    Set a property by name.
 */
static int setXmlListPropertyByName(Ejs *ejs, EjsXML *list, EjsName qname, EjsObj *value)
{
    EjsXML      *elt, *targetObject;
    int         index;

    if (!isdigit((uchar) qname.name->value[0])) {
        return setAlphaPropertyByName(ejs, list, qname, value);
    }

    /*
        Numeric property
     */
    targetObject = 0;
    if (list->targetObject) {
        /*
            Find the real underlying target object. May be an XML object or XMLList if it contains multiple elements.
         */
        targetObject = resolve(ejs, list->targetObject);
        if (targetObject == 0) {
            /* Spec says so - TODO why no error? */
            return 0;
        }
    }
    index = ejsAtoi(ejs, qname.name, 10);
    if (index >= mprGetListLength(list->elements)) {
        /*
            Create, then fall through to update
         */
        elt = createElement(ejs, list, targetObject, qname, value);
        if (elt == 0) {
            return 0;
        }

    } else {
        elt = mprGetItem(list->elements, index);
    }
    assure(elt);
    updateElement(ejs, list, elt, index, value);
    return index;
}
Esempio n. 13
0
/*
    Set an indexed element to an XML value
 */
PUBLIC EjsXML *ejsSetXMLElement(Ejs *ejs, EjsXML *xml, int index, EjsXML *node)
{
    EjsXML      *old;

    if (xml == 0 || node == 0) {
        return 0;
    }
    if (xml->elements == 0) {
        xml->elements = mprCreateList(-1, 0);

    } else {
        old = (EjsXML*) mprGetItem(xml->elements, index);
        if (old && old != node) {
            old->parent = 0;
        }
    }

    if (xml->kind != EJS_XML_LIST) {
        node->parent = xml;
    }
    mprSetItem(xml->elements, index, node);
    return xml;
}
Esempio n. 14
0
/*
    Set an alpha property by name.
 */
static int setAlphaPropertyByName(Ejs *ejs, EjsXML *list, EjsName qname, EjsObj *value)
{
    EjsXML      *elt, *targetObject;
    int         count;

    targetObject = 0;

    count = ejsGetLength(ejs, (EjsObj*) list);
    if (count > 1) {
        //  TODO - why no error in spec?
        assure(0);
        return 0;
    }

    if (count == 0) {
        /*
            Empty list so resolve the real target object and append it to the list.
         */
        targetObject = resolve(ejs, list);
        if (targetObject == 0) {
            return 0;
        }
        if (ejsGetLength(ejs, (EjsObj*) targetObject) != 1) {
            return 0;
        }
        ejsAppendToXML(ejs, list, targetObject);
    }

    /*
        Update the element
     */
    assure(ejsGetLength(ejs, (EjsObj*) list) == 1);
    elt = mprGetItem(list->elements, 0);                        //  TODO OPT - GetFirstItem
    assure(elt);
    ejsSetPropertyByName(ejs, elt, qname, value);
    return 0;
}
Esempio n. 15
0
/*
    Set a property by name
    There are 7 kinds of qname's: prop, @att, [prop], *, @*, .name, .@name
 */
static int setXmlPropertyByName(Ejs *ejs, EjsXML *xml, EjsName qname, EjsObj *value)
{
    EjsXML      *elt, *xvalue, *rp, *lastElt;
    EjsObj      *originalValue;
    int         index, last;

    last = 0;
    lastElt = 0;

    if (isdigit((uchar) qname.name->value[0]) && allDigitsForXml(qname.name)) {
        ejsThrowTypeError(ejs, "Integer indicies for set are not allowed");
        return EJS_ERR;
    }

    if (xml->kind != EJS_XML_ELEMENT) {
        //  TODO spec requires this -- but why? -- surely throw?
        return 0;
    }

    /*
        Massage the value type.
     */
    originalValue = value;

    xvalue = (EjsXML*) value;
    if (ejsIsXML(ejs, xvalue)) {
        if (xvalue->kind == EJS_XML_LIST) {
            value = cloneXml(ejs, xvalue, 1);

        } else if (xvalue->kind == EJS_XML_TEXT || xvalue->kind == EJS_XML_ATTRIBUTE) {
            value = ejsCast(ejs, originalValue, String);

        } else {
            value = cloneXml(ejs, xvalue, 1);
        }
    } else {
        value = ejsCast(ejs, value, String);
    }
    if (qname.name->value[0] == '@') {
        return setXmlPropertyAttributeByName(ejs, xml, qname, value);
    }
    /*
        Delete redundant elements by the same name.
     */
    if (xml->elements) {
        for (last = -1, index = -1; (elt = mprGetPrevItem(xml->elements, &index)) != 0; ) {
            if (qname.name->value[0] == '*' || (elt->kind == EJS_XML_ELEMENT && elt->qname.name == qname.name)) {
                /*
                    Must remove all redundant elements of the same name except the first one
                 */
                if (last >= 0) {
                    rp = mprGetItem(xml->elements, last);
                    rp->parent = 0;
                    mprRemoveItemAtPos(xml->elements, last);
                }
                last = index;
                lastElt = elt;
            }
        }
    }
    if (xml->elements == 0) {
        //  TODO - need routine to do this centrally so we can control the default number of elements in the list?
        xml->elements = mprCreateList(-1, 0);
    }
    elt = lastElt;
    index = last;

    if (qname.name->value[0] == '*') {
        /*
            Special case when called from XMLList to update the value of an element
         */
        xml = createValueNode(ejs, xml, value);

    } else if (elt == 0) {
        /*
            Not found. New node required.
         */
        elt = ejsCreateXML(ejs, EJS_XML_ELEMENT, qname, xml, NULL);
        if (elt == 0) {
            return 0;
        }
        index = mprGetListLength(xml->elements);
        xml = ejsAppendToXML(ejs, xml, createValueNode(ejs, elt, value));

    } else {
        /*
            Update existing element.
         */
        xml = ejsSetXMLElement(ejs, xml, index, createValueNode(ejs, elt, value));
    }

    if (xml == 0) {
        return EJS_ERR;
    }
    return index;
}
Esempio n. 16
0
static EjsXML *createElement(Ejs *ejs, EjsXML *list, EjsXML *targetObject, EjsName qname, EjsObj *value)
{
    EjsXML      *elt, *last, *attList;
    int         index;
    int         j;

    if (targetObject && ejsIsXML(ejs, targetObject) && targetObject->kind == EJS_XML_LIST) {

        /*
            If the target is a list it must have 1 element. So switch to it.
            TODO - could we get resolve to do this?
         */
        if (mprGetListLength(targetObject->elements) != 1) {
            /* Spec says so - TODO why no error? */
            return 0;
        }
        targetObject = mprGetFirstItem(targetObject->elements);
    }

    /*
        Return if the target object is not an XML element
     */
    if (!ejsIsXML(ejs, targetObject) || targetObject->kind != EJS_XML_ELEMENT) {
            /* Spec says so - TODO why no error? */
        return 0;
    }

    elt = ejsCreateXML(ejs, EJS_XML_ELEMENT, list->targetProperty, targetObject, NULL);

    if (list->targetProperty.name && list->targetProperty.name->value[0] == '@') {
        elt->kind = EJS_XML_ATTRIBUTE;
        attList = ejsGetPropertyByName(ejs, (EjsObj*) targetObject, list->targetProperty);
        if (attList && mprGetListLength(attList->elements) > 0) {
            /* Spec says so. But this surely means you can't update an attribute? */
            return 0;
        }
    } else if (list->targetProperty.name == NULL || qname.name->value[0] == '*') {
        elt->kind = EJS_XML_TEXT;
        elt->qname.name = 0;
    }

    index = mprGetListLength(list->elements);

    if (elt->kind != EJS_XML_ATTRIBUTE) {
        if (targetObject) {
            if (index > 0) {
                /*
                    Find the place of the last list item in the resolved target object.
                 */
                last = mprGetItem(list->elements, index - 1);
                j = mprLookupItem(targetObject->elements, last);
            } else {
                j = -1;
            } 
            if (j < 0) {
                j = mprGetListLength(targetObject->elements) - 1;
            }
            //  TODO - really need to wrap this ejsInsertXML(EjsXML *xml, int index, EjsXML *node)
            if (targetObject->elements == 0) {
                targetObject->elements = mprCreateList(-1, 0);
            }
            /*
                Insert into the target object
             */
            mprInsertItemAtPos(targetObject->elements, j + 1, elt);
        }

        if (ejsIsXML(ejs, value)) {
            if (((EjsXML*) value)->kind == EJS_XML_LIST) {
                elt->qname = ((EjsXML*) value)->targetProperty;
            } else {
                elt->qname = ((EjsXML*) value)->qname;
            }
        }

        /*
            Insert into the XML list
         */
        mprSetItem(list->elements, index, elt);
    }
    return (EjsXML*) mprGetItem(list->elements, index);
}