/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"

#if ENABLE(DATABASE)

#include "JSSQLResultSet.h"

#include "JSSQLResultSetRowList.h"
#include "SQLResultSet.h"
#include "SQLResultSetRowList.h"
#include <runtime/JSNumberCell.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSQLResultSet);

/* Hash table */

static const HashTableValue JSSQLResultSetTableValues[4] =
{
    { "rows", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSQLResultSetRows), (intptr_t)0 },
    { "insertId", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSQLResultSetInsertId), (intptr_t)0 },
    { "rowsAffected", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSQLResultSetRowsAffected), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSQLResultSetTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 255, JSSQLResultSetTableValues, 0 };
#else
    { 9, 7, JSSQLResultSetTableValues, 0 };
#endif

/* Hash table for prototype */

static const HashTableValue JSSQLResultSetPrototypeTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSQLResultSetPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSSQLResultSetPrototypeTableValues, 0 };
#else
    { 1, 0, JSSQLResultSetPrototypeTableValues, 0 };
#endif

const ClassInfo JSSQLResultSetPrototype::s_info = { "SQLResultSetPrototype", 0, &JSSQLResultSetPrototypeTable, 0 };

JSObject* JSSQLResultSetPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSSQLResultSet>(exec, globalObject);
}

const ClassInfo JSSQLResultSet::s_info = { "SQLResultSet", 0, &JSSQLResultSetTable, 0 };

JSSQLResultSet::JSSQLResultSet(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<SQLResultSet> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSSQLResultSet::~JSSQLResultSet()
{
    forgetDOMObject(this, impl());
}

JSObject* JSSQLResultSet::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSSQLResultSetPrototype(JSSQLResultSetPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSSQLResultSet::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSQLResultSet, Base>(exec, &JSSQLResultSetTable, this, propertyName, slot);
}

bool JSSQLResultSet::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSQLResultSet, Base>(exec, &JSSQLResultSetTable, this, propertyName, descriptor);
}

JSValue jsSQLResultSetRows(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSQLResultSet* castedThis = static_cast<JSSQLResultSet*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SQLResultSet* imp = static_cast<SQLResultSet*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->rows()));
    return result;
}

JSValue jsSQLResultSetInsertId(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSQLResultSet* castedThis = static_cast<JSSQLResultSet*>(asObject(slotBase));
    ExceptionCode ec = 0;
    SQLResultSet* imp = static_cast<SQLResultSet*>(castedThis->impl());
    JSC::JSValue result = jsNumber(exec, imp->insertId(ec));
    setDOMException(exec, ec);
    return result;
}

JSValue jsSQLResultSetRowsAffected(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSQLResultSet* castedThis = static_cast<JSSQLResultSet*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SQLResultSet* imp = static_cast<SQLResultSet*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->rowsAffected());
    return result;
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, SQLResultSet* object)
{
    return getDOMObjectWrapper<JSSQLResultSet>(exec, globalObject, object);
}
SQLResultSet* toSQLResultSet(JSC::JSValue value)
{
    return value.inherits(&JSSQLResultSet::s_info) ? static_cast<JSSQLResultSet*>(asObject(value))->impl() : 0;
}

}

#endif // ENABLE(DATABASE)
