From: Michael Tremer Date: Fri, 30 Dec 2016 13:25:58 +0000 (+0100) Subject: Extend Python bindings to use libpakfire for dependency resolution X-Git-Tag: 0.9.28~1285^2~1359 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b62fe40d5f78d276647ce3f2dee39cac5b54907;p=pakfire.git Extend Python bindings to use libpakfire for dependency resolution Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 86ebeaedd..a39ba9044 100644 --- a/Makefile.am +++ b/Makefile.am @@ -195,12 +195,12 @@ _pakfire_la_SOURCES = \ src/_pakfire/repo.h \ src/_pakfire/request.c \ src/_pakfire/request.h \ + src/_pakfire/selector.c \ + src/_pakfire/selector.h \ src/_pakfire/solution.c \ src/_pakfire/solution.h \ src/_pakfire/solvable.c \ src/_pakfire/solvable.h \ - src/_pakfire/solver.c \ - src/_pakfire/solver.h \ src/_pakfire/step.c \ src/_pakfire/step.h \ src/_pakfire/transaction.c \ diff --git a/src/_pakfire/_pakfiremodule.c b/src/_pakfire/_pakfiremodule.c index 9d55f4d01..773e090fa 100644 --- a/src/_pakfire/_pakfiremodule.c +++ b/src/_pakfire/_pakfiremodule.c @@ -36,7 +36,6 @@ #include "request.h" #include "solution.h" #include "solvable.h" -#include "solver.h" #include "step.h" #include "transaction.h" #include "util.h" @@ -61,28 +60,6 @@ static PyMethodDef Problem_methods[] = { { NULL, NULL, 0, NULL } }; -static PyMethodDef Request_methods[] = { - {"install_solvable", (PyCFunction)Request_install_solvable, METH_VARARGS, NULL}, - {"install_relation", (PyCFunction)Request_install_relation, METH_VARARGS, NULL}, - {"install_name", (PyCFunction)Request_install_name, METH_VARARGS, NULL}, - {"remove_solvable", (PyCFunction)Request_remove_solvable, METH_VARARGS, NULL}, - {"remove_relation", (PyCFunction)Request_remove_relation, METH_VARARGS, NULL}, - {"remove_name", (PyCFunction)Request_remove_name, METH_VARARGS, NULL}, - {"update_solvable", (PyCFunction)Request_update_solvable, METH_VARARGS, NULL}, - {"update_relation", (PyCFunction)Request_update_relation, METH_VARARGS, NULL}, - {"update_name", (PyCFunction)Request_update_name, METH_VARARGS, NULL}, - {"lock_solvable", (PyCFunction)Request_lock_solvable, METH_VARARGS, NULL}, - {"lock_relation", (PyCFunction)Request_lock_relation, METH_VARARGS, NULL}, - {"lock_name", (PyCFunction)Request_lock_name, METH_VARARGS, NULL}, - {"noobsoletes_solvable", (PyCFunction)Request_noobsoletes_solvable, METH_VARARGS, NULL}, - {"noobsoletes_relation", (PyCFunction)Request_noobsoletes_relation, METH_VARARGS, NULL}, - {"noobsoletes_name", (PyCFunction)Request_noobsoletes_name, METH_VARARGS, NULL}, - {"updateall", (PyCFunction)Request_updateall, METH_NOARGS, NULL}, - {"distupgrade", (PyCFunction)Request_distupgrade, METH_NOARGS, NULL}, - {"verify", (PyCFunction)Request_verify, METH_NOARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - static PyMethodDef Solvable_methods[] = { {"get_name", (PyCFunction)Solvable_get_name, METH_NOARGS, NULL}, {"get_evr", (PyCFunction)Solvable_get_evr, METH_NOARGS, NULL}, @@ -135,36 +112,6 @@ static PyMethodDef Solution_methods[] = { { NULL, NULL, 0, NULL } }; -static PyMethodDef Solver_methods[] = { - {"solve", (PyCFunction)Solver_solve, METH_VARARGS, NULL}, - {"get_flag", (PyCFunction)Solver_get_flag, METH_VARARGS, NULL}, - {"set_flag", (PyCFunction)Solver_set_flag, METH_VARARGS, NULL}, - {"get_allow_archchange", (PyCFunction)Solver_get_allow_archchange, METH_NOARGS, NULL}, - {"set_allow_archchange", (PyCFunction)Solver_set_allow_archchange, METH_VARARGS, NULL}, - {"get_allow_vendorchange", (PyCFunction)Solver_get_allow_vendorchange, METH_NOARGS, NULL}, - {"set_allow_vendorchange", (PyCFunction)Solver_set_allow_vendorchange, METH_VARARGS, NULL}, - {"get_allow_uninstall", (PyCFunction)Solver_get_allow_uninstall, METH_NOARGS, NULL}, - {"set_allow_uninstall", (PyCFunction)Solver_set_allow_uninstall, METH_VARARGS, NULL}, - {"get_updatesystem", (PyCFunction)Solver_get_updatesystem, METH_NOARGS, NULL}, - {"set_updatesystem", (PyCFunction)Solver_set_updatesystem, METH_VARARGS, NULL}, - {"get_do_split_provides", (PyCFunction)Solver_get_do_split_provides, METH_NOARGS, NULL}, - {"set_do_split_provides", (PyCFunction)Solver_set_do_split_provides, METH_VARARGS, NULL}, - {"get_problems", (PyCFunction)Solver_get_problems, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - -static PyMethodDef Step_methods[] = { - {"get_solvable", (PyCFunction)Step_get_solvable, METH_NOARGS, NULL}, - {"get_type", (PyCFunction)Step_get_type, METH_NOARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - -static PyMethodDef Transaction_methods[] = { - {"steps", (PyCFunction)Transaction_steps, METH_NOARGS, NULL}, - {"get_installsizechange", (PyCFunction)Transaction_get_installsizechange, METH_NOARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - static struct PyModuleDef moduledef = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "_pakfire", @@ -232,9 +179,9 @@ PyMODINIT_FUNC PyInit__pakfire(void) { PyModule_AddObject(module, "Relation", (PyObject *)&RelationType); // Request - RequestType.tp_methods = Request_methods; if (PyType_Ready(&RequestType) < 0) return NULL; + Py_INCREF(&RequestType); PyModule_AddObject(module, "Request", (PyObject *)&RequestType); @@ -245,27 +192,27 @@ PyMODINIT_FUNC PyInit__pakfire(void) { Py_INCREF(&SolutionType); PyModule_AddObject(module, "Solution", (PyObject *)&SolutionType); - // Solver - SolverType.tp_methods = Solver_methods; - if (PyType_Ready(&SolverType) < 0) - return NULL; - Py_INCREF(&SolverType); - PyModule_AddObject(module, "Solver", (PyObject *)&SolverType); - // Step - StepType.tp_methods = Step_methods; if (PyType_Ready(&StepType) < 0) return NULL; + Py_INCREF(&StepType); PyModule_AddObject(module, "Step", (PyObject *)&StepType); // Transaction - TransactionType.tp_methods = Transaction_methods; if (PyType_Ready(&TransactionType) < 0) return NULL; + Py_INCREF(&TransactionType); PyModule_AddObject(module, "Transaction", (PyObject *)&TransactionType); + // Transaction Iterator + if (PyType_Ready(&TransactionIteratorType) < 0) + return NULL; + + Py_INCREF(&TransactionIteratorType); + PyModule_AddObject(module, "TransactionIterator", (PyObject *)&TransactionIteratorType); + // Add constants PyObject* d = PyModule_GetDict(module); diff --git a/src/_pakfire/request.c b/src/_pakfire/request.c index a899b9ce7..0ac6db627 100644 --- a/src/_pakfire/request.c +++ b/src/_pakfire/request.c @@ -18,249 +18,268 @@ # # #############################################################################*/ -#include "pool.h" -#include "relation.h" -#include "request.h" -#include "solvable.h" - -#include +#include +#include -PyTypeObject RequestType = { - PyVarObject_HEAD_INIT(NULL, 0) - tp_name: "_pakfire.Request", - tp_basicsize: sizeof(RequestObject), - tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - tp_new : Request_new, - tp_dealloc: (destructor) Request_dealloc, - tp_doc: "Sat Request objects", -}; - -PyObject* Request_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - RequestObject *self; - PoolObject *pool; - - if (!PyArg_ParseTuple(args, "O", &pool)) { - /* XXX raise exception */ - } +#include +#include - self = (RequestObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->_pool = pool->_pool; - if (self->_pool == NULL) { - Py_DECREF(self); - return NULL; - } - - queue_init(&self->_queue); +#include "package.h" +#include "relation.h" +#include "request.h" +#include "selector.h" +#include "transaction.h" + +static PyObject* Request_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { + RequestObject* self = (RequestObject *)type->tp_alloc(type, 0); + if (self) { + self->request = NULL; + self->pool = NULL; } return (PyObject *)self; } -PyObject *Request_dealloc(RequestObject *self) { - Py_TYPE(self)->tp_free((PyObject *)self); - - Py_RETURN_NONE; -} +static void Request_dealloc(RequestObject* self) { + if (self->request) + pakfire_request_free(self->request); -void _Request_solvable(RequestObject *self, Id what, Id solvable) { - queue_push2(&self->_queue, what|SOLVER_SOLVABLE, solvable); + Py_XDECREF(self->pool); + Py_TYPE(self)->tp_free((PyObject *)self); } -void _Request_relation(RequestObject *self, Id what, Id relation) { - queue_push2(&self->_queue, what|SOLVER_SOLVABLE_PROVIDES, relation); -} +static int Request_init(RequestObject* self, PyObject* args, PyObject* kwds) { + PyObject* pool; -void _Request_name(RequestObject *self, Id what, Id provides) { - queue_push2(&self->_queue, what|SOLVER_SOLVABLE_NAME, provides); -} + if (!PyArg_ParseTuple(args, "O!", &PoolType, &pool)) + return -1; -PyObject *Request_install_solvable(RequestObject *self, PyObject *args) { - SolvableObject *solv; + self->pool = (PoolObject *)pool; + Py_INCREF(self->pool); - if (!PyArg_ParseTuple(args, "O", &solv)) { - return NULL; - } + self->request = pakfire_request_create(self->pool->pool); - _Request_solvable(self, SOLVER_INSTALL, solv->_id); - Py_RETURN_NONE; + return 0; } -PyObject *Request_install_relation(RequestObject *self, PyObject *args) { - RelationObject *rel; +static int Request_args_parse(PyObject* args, PakfirePackage* pkg, PakfireRelation* relation, PakfireSelector* selector) { + PyObject* obj = NULL; - if (!PyArg_ParseTuple(args, "O", &rel)) { - return NULL; - } - - _Request_relation(self, SOLVER_INSTALL, rel->_id); - Py_RETURN_NONE; -} + if (!PyArg_ParseTuple(args, "O", &obj)) + return 0; -PyObject *Request_install_name(RequestObject *self, PyObject *args) { - const char *name; + if (PyObject_TypeCheck(obj, &PackageType)) { + PackageObject* pkg_obj = (PackageObject *)obj; + *pkg = pkg_obj->package; - if (!PyArg_ParseTuple(args, "s", &name)) { - return NULL; + return 1; } - Id _name = pool_str2id(self->_pool, name, 1); - _Request_name(self, SOLVER_INSTALL, _name); + if (PyObject_TypeCheck(obj, &RelationType)) { + RelationObject* relation_obj = (RelationObject *)obj; + *relation = relation_obj->relation; - Py_RETURN_NONE; -} + return 1; + } -PyObject *Request_remove_solvable(RequestObject *self, PyObject *args) { - SolvableObject *solv; + if (PyObject_TypeCheck(obj, &SelectorType)) { + SelectorObject* selector_obj = (SelectorObject *)obj; + *selector = selector_obj->selector; - if (!PyArg_ParseTuple(args, "O", &solv)) { - return NULL; + return 1; } - _Request_solvable(self, SOLVER_ERASE, solv->_id); - Py_RETURN_NONE; + PyErr_SetString(PyExc_ValueError, "Requires a Package, Relation or Selector object"); + return 0; } -PyObject *Request_remove_relation(RequestObject *self, PyObject *args) { - RelationObject *rel; +static PyObject* Request_operation_return(int ret) { + if (!ret) + Py_RETURN_NONE; - if (!PyArg_ParseTuple(args, "O", &rel)) { - return NULL; - } + switch (pakfire_get_errno()) { + case PAKFIRE_E_SELECTOR: + PyErr_SetString(PyExc_ValueError, "Ill-formed Selector"); + return NULL; - _Request_relation(self, SOLVER_ERASE, rel->_id); - Py_RETURN_NONE; + default: + PyErr_SetString(PyExc_RuntimeError, "Request operation failed"); + return NULL; + } } -PyObject *Request_remove_name(RequestObject *self, PyObject *args) { - const char *name; +static PyObject* Request_install(RequestObject* self, PyObject* args) { + PakfirePackage pkg = NULL; + PakfireRelation relation = NULL; + PakfireSelector selector = NULL; - if (!PyArg_ParseTuple(args, "s", &name)) { + if (!Request_args_parse(args, &pkg, &relation, &selector)) return NULL; - } - Id _name = pool_str2id(self->_pool, name, 1); - _Request_name(self, SOLVER_ERASE, _name); + assert(pkg || relation || selector); - Py_RETURN_NONE; -} + int ret = 0; -PyObject *Request_update_solvable(RequestObject *self, PyObject *args) { - SolvableObject *solv; + if (pkg) + ret = pakfire_request_install(self->request, pkg); - if (!PyArg_ParseTuple(args, "O", &solv)) { - return NULL; - } + else if (relation) + ret = pakfire_request_install_relation(self->request, relation); + + else if (selector) + ret = pakfire_request_install_selector(self->request, selector); - _Request_solvable(self, SOLVER_UPDATE, solv->_id); - Py_RETURN_NONE; + return Request_operation_return(ret); } -PyObject *Request_update_relation(RequestObject *self, PyObject *args) { - RelationObject *rel; +static PyObject* Request_erase(RequestObject* self, PyObject* args) { + PakfirePackage pkg = NULL; + PakfireRelation relation = NULL; + PakfireSelector selector = NULL; - if (!PyArg_ParseTuple(args, "O", &rel)) { + if (!Request_args_parse(args, &pkg, &relation, &selector)) return NULL; - } - _Request_relation(self, SOLVER_UPDATE, rel->_id); - Py_RETURN_NONE; -} + assert(pkg || relation || selector); -PyObject *Request_update_name(RequestObject *self, PyObject *args) { - const char *name; + int ret = 0; - if (!PyArg_ParseTuple(args, "s", &name)) { - return NULL; - } + if (pkg) + ret = pakfire_request_erase(self->request, pkg, 0); - Id _name = pool_str2id(self->_pool, name, 1); - _Request_name(self, SOLVER_UPDATE, _name); + else if (selector) + ret = pakfire_request_erase_selector(self->request, selector, 0); - Py_RETURN_NONE; + return Request_operation_return(ret); } -PyObject *Request_lock_solvable(RequestObject *self, PyObject *args) { - SolvableObject *solv; +static PyObject* Request_upgrade(RequestObject* self, PyObject* args) { + PakfirePackage pkg = NULL; + PakfireRelation relation = NULL; + PakfireSelector selector = NULL; - if (!PyArg_ParseTuple(args, "O", &solv)) { + if (!Request_args_parse(args, &pkg, &relation, &selector)) return NULL; - } - _Request_solvable(self, SOLVER_LOCK, solv->_id); - Py_RETURN_NONE; -} + assert(pkg || relation || selector); -PyObject *Request_lock_relation(RequestObject *self, PyObject *args) { - RelationObject *rel; + int ret = 0; - if (!PyArg_ParseTuple(args, "O", &rel)) { - return NULL; - } + if (pkg) + ret = pakfire_request_upgrade(self->request, pkg); - _Request_relation(self, SOLVER_LOCK, rel->_id); - Py_RETURN_NONE; -} + else if (relation) + ret = pakfire_request_upgrade_relation(self->request, relation); -PyObject *Request_lock_name(RequestObject *self, PyObject *args) { - const char *name; + else if (selector) + ret = pakfire_request_upgrade_selector(self->request, selector); - if (!PyArg_ParseTuple(args, "s", &name)) { - return NULL; - } + return Request_operation_return(ret); +} - Id _name = pool_str2id(self->_pool, name, 1); - _Request_name(self, SOLVER_LOCK, _name); +static PyObject* Request_upgrade_all(RequestObject* self) { + int ret = pakfire_request_upgrade_all(self->request); - Py_RETURN_NONE; + return Request_operation_return(ret); } -PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *args) { - SolvableObject *solv; +static PyObject* Request_distupgrade(RequestObject* self) { + int ret = pakfire_request_distupgrade(self->request); - if (!PyArg_ParseTuple(args, "O", &solv)) { - return NULL; - } - - _Request_solvable(self, SOLVER_NOOBSOLETES, solv->_id); - Py_RETURN_NONE; + return Request_operation_return(ret); } -PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args) { - RelationObject *rel; +static PyObject* Request_solve(RequestObject* self) { + int ret = pakfire_request_solve(self->request, 0); - if (!PyArg_ParseTuple(args, "O", &rel)) { - return NULL; - } + if (ret) + Py_RETURN_FALSE; - _Request_relation(self, SOLVER_NOOBSOLETES, rel->_id); - Py_RETURN_NONE; + Py_RETURN_TRUE; } -PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args) { - const char *name; +static PyObject* Request_get_transaction(RequestObject* self) { + PakfireTransaction transaction = pakfire_request_get_transaction(self->request); - if (!PyArg_ParseTuple(args, "s", &name)) { - return NULL; - } + if (!transaction) + Py_RETURN_NONE; - Id _name = pool_str2id(self->_pool, name, 1); - _Request_name(self, SOLVER_NOOBSOLETES, _name); - - Py_RETURN_NONE; + return new_transaction(self, transaction); } -PyObject *Request_updateall(RequestObject *self, PyObject *args) { - queue_push2(&self->_queue, SOLVER_UPDATE|SOLVER_SOLVABLE_ALL, 0); - Py_RETURN_NONE; -} +static PyObject* Request_get_pool(RequestObject* self) { + PoolObject* pool = self->pool; + Py_INCREF(pool); -PyObject *Request_distupgrade(RequestObject *self, PyObject *args) { - queue_push2(&self->_queue, SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL, 0); - Py_RETURN_NONE; + return (PyObject *)pool; } -PyObject *Request_verify(RequestObject *self, PyObject *args) { - queue_push2(&self->_queue, SOLVER_VERIFY|SOLVER_SOLVABLE_ALL, 0); - Py_RETURN_NONE; -} +static struct PyMethodDef Request_methods[] = { + { + "install", + (PyCFunction)Request_install, + METH_VARARGS, + NULL + }, + { + "erase", + (PyCFunction)Request_erase, + METH_VARARGS, + NULL + }, + { + "upgrade", + (PyCFunction)Request_upgrade, + METH_VARARGS, + NULL + }, + { + "upgrade_all", + (PyCFunction)Request_upgrade_all, + METH_NOARGS, + NULL + }, + { + "distupgrade", + (PyCFunction)Request_distupgrade, + METH_NOARGS, + NULL + }, + { + "solve", + (PyCFunction)Request_solve, + METH_NOARGS, + NULL + }, + { + "get_transaction", + (PyCFunction)Request_get_transaction, + METH_NOARGS, + NULL + }, + { NULL } +}; + +static struct PyGetSetDef Request_getsetters[] = { + { + "pool", + (getter)Request_get_pool, + NULL, + NULL, + NULL + }, + { NULL }, +}; + +PyTypeObject RequestType = { + PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "_pakfire.Request", + tp_basicsize: sizeof(RequestObject), + tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + tp_new: Request_new, + tp_dealloc: (destructor)Request_dealloc, + tp_init: (initproc)Request_init, + tp_doc: "Request object", + tp_methods: Request_methods, + tp_getset: Request_getsetters, +}; diff --git a/src/_pakfire/request.h b/src/_pakfire/request.h index f7c2efe06..6ced13645 100644 --- a/src/_pakfire/request.h +++ b/src/_pakfire/request.h @@ -23,45 +23,18 @@ #include -#include +#include -// Sat Request object -typedef struct { - PyObject_HEAD - Pool *_pool; - Queue _queue; -} RequestObject; - -extern PyObject* Request_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -extern PyObject *Request_dealloc(RequestObject *self); - -extern void _Request_solvable(RequestObject *self, Id what, Id solvable); -extern void _Request_relation(RequestObject *self, Id what, Id relation); -extern void _Request_name(RequestObject *self, Id what, Id provides); - -extern PyObject *Request_install_solvable(RequestObject *self, PyObject *args); -extern PyObject *Request_install_relation(RequestObject *self, PyObject *args); -extern PyObject *Request_install_name(RequestObject *self, PyObject *args); +#include "pool.h" -extern PyObject *Request_remove_solvable(RequestObject *self, PyObject *args); -extern PyObject *Request_remove_relation(RequestObject *self, PyObject *args); -extern PyObject *Request_remove_name(RequestObject *self, PyObject *args); - -extern PyObject *Request_update_solvable(RequestObject *self, PyObject *args); -extern PyObject *Request_update_relation(RequestObject *self, PyObject *args); -extern PyObject *Request_update_name(RequestObject *self, PyObject *args); - -extern PyObject *Request_lock_solvable(RequestObject *self, PyObject *args); -extern PyObject *Request_lock_relation(RequestObject *self, PyObject *args); -extern PyObject *Request_lock_name(RequestObject *self, PyObject *args); - -extern PyObject *Request_noobsoletes_solvable(RequestObject *self, PyObject *args); -extern PyObject *Request_noobsoletes_relation(RequestObject *self, PyObject *args); -extern PyObject *Request_noobsoletes_name(RequestObject *self, PyObject *args); +typedef struct { + PyObject_HEAD + PoolObject* pool; + PakfireRequest request; -extern PyObject *Request_updateall(RequestObject *self, PyObject *args); -extern PyObject *Request_distupgrade(RequestObject *self, PyObject *args); -extern PyObject *Request_verify(RequestObject *self, PyObject *args); + // XXX COMPAT + Pool* _pool; +} RequestObject; extern PyTypeObject RequestType; diff --git a/src/_pakfire/selector.c b/src/_pakfire/selector.c new file mode 100644 index 000000000..57c7dc1e4 --- /dev/null +++ b/src/_pakfire/selector.c @@ -0,0 +1,133 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2011 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program 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 General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "package.h" +#include "selector.h" + +static PyObject* Selector_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { + SelectorObject* self = (SelectorObject *)type->tp_alloc(type, 0); + if (self) { + self->pool = NULL; + self->selector = NULL; + } + + return (PyObject *)self; +} + +static void Selector_dealloc(SelectorObject* self) { + if (self->selector) + pakfire_selector_free(self->selector); + + Py_XDECREF(self->pool); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int Selector_init(SelectorObject* self, PyObject* args, PyObject* kwds) { + PyObject* pool; + + if (!PyArg_ParseTuple(args, "O!", &PoolType, &pool)) + return -1; + + self->pool = (PoolObject *)pool; + Py_INCREF(self->pool); + + self->selector = pakfire_selector_create(self->pool->pool); + + return 0; +} + +static PyObject* Selector_set(SelectorObject* self, PyObject* args) { + int keyname; + int cmp_type; + const char* match; + + if (!PyArg_ParseTuple(args, "iis", &keyname, &cmp_type, &match)) + return NULL; + + int ret = pakfire_selector_set(self->selector, keyname, cmp_type, match); + + switch (ret) { + case PAKFIRE_E_SELECTOR: + PyErr_SetString(PyExc_ValueError, "Invalid Selector specification"); + return NULL; + + default: + Py_RETURN_NONE; + } +} + +static PyObject* Selector_get_providers(SelectorObject* self) { + PakfirePackageList packagelist = pakfire_selector_providers(self->selector); + + PyObject* list = PyList_New(0); + PakfirePackage package; + int i; + + FOR_PACKAGELIST(package, packagelist, i) { + PyObject* obj = new_package(self->pool, pakfire_package_id(package)); + PyList_Append(list, obj); + } + pakfire_packagelist_free(packagelist); + + return list; +} + +static struct PyGetSetDef Selector_getsetters[] = { + { + "providers", + (getter)Selector_get_providers, + NULL, + NULL, + NULL + }, + { NULL }, +}; + +static struct PyMethodDef Selector_methods[] = { + { + "set", + (PyCFunction)Selector_set, + METH_VARARGS, + NULL + }, + { NULL }, +}; + +PyTypeObject SelectorType = { + PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "_pakfire.Selector", + tp_basicsize: sizeof(SelectorObject), + tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + tp_new: Selector_new, + tp_dealloc: (destructor)Selector_dealloc, + tp_init: (initproc)Selector_init, + tp_doc: "Selector object", + tp_methods: Selector_methods, + tp_getset: Selector_getsetters, +}; diff --git a/src/_pakfire/selector.h b/src/_pakfire/selector.h new file mode 100644 index 000000000..577d83f71 --- /dev/null +++ b/src/_pakfire/selector.h @@ -0,0 +1,38 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2011 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program 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 General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef PYTHON_PAKFIRE_SELECTOR_H +#define PYTHON_PAKFIRE_SELECTOR_H + +#include + +#include + +#include "pool.h" + +typedef struct { + PyObject_HEAD + PoolObject* pool; + PakfireSelector selector; +} SelectorObject; + +extern PyTypeObject SelectorType; + +#endif /* PYTHON_PAKFIRE_SELECTOR_H */ diff --git a/src/_pakfire/step.c b/src/_pakfire/step.c index 32c6b68c2..3c79cf3a6 100644 --- a/src/_pakfire/step.c +++ b/src/_pakfire/step.c @@ -18,133 +18,170 @@ # # #############################################################################*/ -#include "solvable.h" +#include + +#include +#include +#include +#include + +#include "package.h" #include "step.h" #include "transaction.h" -PyTypeObject StepType = { - PyVarObject_HEAD_INIT(NULL, 0) - tp_name: "_pakfire.Step", - tp_basicsize: sizeof(StepObject), - tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - tp_new : Step_new, - tp_dealloc: (destructor) Step_dealloc, - tp_doc: "Sat Step objects", -}; - -PyObject* Step_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - StepObject *self; - TransactionObject *transaction; - int num; +static StepObject* Step_new_core(PyTypeObject* type, TransactionObject* transaction) { + StepObject* self = (StepObject *)type->tp_alloc(type, 0); + if (!self) + return NULL; - if (!PyArg_ParseTuple(args, "Oi", &transaction, &num)) { - /* XXX raise exception */ + if (transaction) { + self->transaction = transaction; + Py_INCREF(self->transaction); } - self = (StepObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->_transaction = transaction->_transaction; + self->step = NULL; - if (num >= transaction->_transaction->steps.count) { - Py_DECREF(self); - return NULL; - } + return self; +} - self->_id = transaction->_transaction->steps.elements[num]; - } +PyObject* new_step(TransactionObject* transaction, PakfireStep s) { + StepObject* step = Step_new_core(&StepType, transaction); + step->step = s; - return (PyObject *)self; + return (PyObject *)step; } -PyObject *Step_dealloc(StepObject *self) { - Py_TYPE(self)->tp_free((PyObject *)self); +static PyObject* Step_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { + StepObject* self = Step_new_core(type, NULL); - Py_RETURN_NONE; + return (PyObject *)self; } -PyObject *Step_get_solvable(StepObject *self, PyObject *args) { - SolvableObject *solvable; +static void Step_dealloc(StepObject* self) { + if (self->step) + pakfire_step_free(self->step); - solvable = PyObject_New(SolvableObject, &SolvableType); - if (solvable == NULL) - return NULL; + Py_XDECREF(self->transaction); + Py_TYPE(self)->tp_free((PyObject *)self); +} - solvable->_pool = self->_transaction->pool; - solvable->_id = self->_id; +static int Step_init(StepObject* self, PyObject* args, PyObject* kwds) { + TransactionObject* transaction; + int index = 0; - return (PyObject *)solvable; -} + if (!PyArg_ParseTuple(args, "O!i", &TransactionType, &transaction, &index)) + return -1; -PyObject *Step_get_type(StepObject *self, PyObject *args) { - const char *type = "unknown"; + self->transaction = transaction; + Py_INCREF(self->transaction); - int trans_type = transaction_type(self->_transaction, self->_id, - SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_CHANGE_IS_REINSTALL); + self->step = pakfire_transaction_get_step(transaction->transaction, index); + if (!self->step) { + PyErr_SetString(PyExc_AttributeError, "No such step"); + return -1; + } - switch(trans_type) { - case SOLVER_TRANSACTION_IGNORE: - type = "ignore"; - break; + return 0; +} - case SOLVER_TRANSACTION_ERASE: - type = "erase"; - break; +static PyObject* Step_repr(StepObject* self) { + PakfirePackage package = pakfire_step_get_package(self->step); + char* nevra = pakfire_package_get_nevra(package); - case SOLVER_TRANSACTION_REINSTALLED: - type = "reinstalled"; - break; + PyObject* repr = PyUnicode_FromFormat("<_pakfire.Step object type %s, %s>", + pakfire_step_get_type_string(self->step), nevra); - case SOLVER_TRANSACTION_DOWNGRADED: - type = "downgraded"; - break; + pakfire_package_free(package); + pakfire_free(nevra); - case SOLVER_TRANSACTION_CHANGED: - type = "changed"; - break; + return repr; +} - case SOLVER_TRANSACTION_UPGRADED: - type = "upgraded"; - break; +static PyObject* Step_get_package(StepObject* self) { + PakfirePackage package = pakfire_step_get_package(self->step); - case SOLVER_TRANSACTION_OBSOLETED: - type = "obsoleted"; - break; + PyObject* obj = new_package(self->transaction->request->pool, pakfire_package_id(package)); + pakfire_package_free(package); - case SOLVER_TRANSACTION_INSTALL: - type = "install"; - break; + return obj; +} - case SOLVER_TRANSACTION_REINSTALL: - type = "reinstall"; - break; +static PyObject* Step_get_type(StepObject* self) { + const char* type = pakfire_step_get_type_string(self->step); - case SOLVER_TRANSACTION_DOWNGRADE: - type = "downgrade"; - break; + if (!type) + Py_RETURN_NONE; - case SOLVER_TRANSACTION_CHANGE: - type = "change"; - break; + return PyUnicode_FromString(type); +} - case SOLVER_TRANSACTION_UPGRADE: - type = "upgrade"; - break; +static PyObject* Step_get_downloadsize(StepObject* self) { + unsigned long long downloadsize = pakfire_step_get_downloadsize(self->step); - case SOLVER_TRANSACTION_OBSOLETES: - type = "obsoletes"; - break; + return PyLong_FromUnsignedLongLong(downloadsize); +} - case SOLVER_TRANSACTION_MULTIINSTALL: - type = "multiinstall"; - break; +static PyObject* Step_get_installsizechange(StepObject* self) { + long installsizechange = pakfire_step_get_installsizechange(self->step); - case SOLVER_TRANSACTION_MULTIREINSTALL: - type = "multireinstall"; - break; + return PyLong_FromLong(installsizechange); +} - default: - break; - } +static PyObject* Step_needs_download(StepObject* self) { + if (pakfire_step_needs_download(self->step)) + Py_RETURN_TRUE; - return Py_BuildValue("s", type); + Py_RETURN_FALSE; } + +static struct PyGetSetDef Step_getsetters[] = { + { + "downloadsize", + (getter)Step_get_downloadsize, + NULL, + NULL, + NULL + }, + { + "installsizechange", + (getter)Step_get_installsizechange, + NULL, + NULL, + NULL + }, + { + "needs_download", + (getter)Step_needs_download, + NULL, + NULL, + NULL + }, + { + "package", + (getter)Step_get_package, + NULL, + NULL, + NULL + }, + { + "type", + (getter)Step_get_type, + NULL, + NULL, + NULL + }, + { NULL }, +}; + +PyTypeObject StepType = { + PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "_pakfire.Step", + tp_basicsize: sizeof(StepObject), + tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + tp_new: Step_new, + tp_dealloc: (destructor)Step_dealloc, + tp_init: (initproc)Step_init, + tp_doc: "Step object", + tp_repr: (reprfunc)Step_repr, + tp_getset: Step_getsetters, +}; diff --git a/src/_pakfire/step.h b/src/_pakfire/step.h index eab1d6cfa..f218318b5 100644 --- a/src/_pakfire/step.h +++ b/src/_pakfire/step.h @@ -23,21 +23,18 @@ #include -#include -#include +#include + +#include "transaction.h" -// Sat Step object typedef struct { - PyObject_HEAD - Transaction *_transaction; - Id _id; + PyObject_HEAD + TransactionObject* transaction; + PakfireStep step; } StepObject; -extern PyObject* Step_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -extern PyObject *Step_dealloc(StepObject *self); -extern PyObject *Step_get_type(StepObject *self, PyObject *args); -extern PyObject *Step_get_solvable(StepObject *self, PyObject *args); - extern PyTypeObject StepType; +PyObject* new_step(TransactionObject* transaction, PakfireStep step); + #endif /* PYTHON_PAKFIRE_STEP_H */ diff --git a/src/_pakfire/transaction.c b/src/_pakfire/transaction.c index cbda77577..d6032a234 100644 --- a/src/_pakfire/transaction.c +++ b/src/_pakfire/transaction.c @@ -20,71 +20,169 @@ #include -#include +#include +#include +#include -#include "solver.h" +#include "package.h" #include "step.h" #include "transaction.h" +#include "util.h" + +static TransactionObject* Transaction_new_core(PyTypeObject* type, RequestObject* request) { + TransactionObject* self = (TransactionObject *)type->tp_alloc(type, 0); + if (!self) + return NULL; + + if (request) { + self->request = request; + Py_INCREF(self->request); + } + + self->transaction = NULL; + + return self; +} + +PyObject* new_transaction(RequestObject* request, PakfireTransaction trans) { + TransactionObject* transaction = Transaction_new_core(&TransactionType, request); + transaction->transaction = trans; + + return (PyObject *)transaction; +} + +static PyObject* Transaction_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { + TransactionObject* self = Transaction_new_core(type, NULL); + + return (PyObject *)self; +} + +static void Transaction_dealloc(TransactionObject* self) { + if (self->transaction) + pakfire_transaction_free(self->transaction); + + Py_XDECREF(self->request); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int Transaction_init(TransactionObject* self, PyObject* args, PyObject* kwds) { + RequestObject* request; + + if (!PyArg_ParseTuple(args, "O!", &RequestType, &request)) + return -1; + + self->request = request; + Py_INCREF(self->request); + + PakfireRequest req = request->request; + self->transaction = pakfire_request_get_transaction(req); + + // If request has got no transaction, we will create an (empty) new one. + if (!self->transaction) { + PakfirePool pool = pakfire_request_pool(req); + + self->transaction = pakfire_transaction_create(pool, NULL); + } + + return 0; +} + +static PyObject* Transaction_iter(TransactionObject* self) { + TransactionIteratorObject* iterator = PyObject_New(TransactionIteratorObject, &TransactionIteratorType); + + iterator->transaction = self; + Py_INCREF(iterator->transaction); + + iterator->iterator = 0; + + return (PyObject *)iterator; +} + +static PyObject* Transaction_get_installsizechange(TransactionObject* self) { + long installsizechange = pakfire_transaction_installsizechange(self->transaction); + + return PyLong_FromLong(installsizechange); +} + +#if 0 +static PyObject* Transaction_get_installs(TransactionObject* self) { + PakfirePackageList packagelist = pakfire_transaction_get_packages(self->transaction, + SOLVER_TRANSACTION_INSTALL); + + PyObject* list = PyList_FromPackageList(self->request->pool, packagelist); + return list; +} +#endif + +static struct PyGetSetDef Transaction_getsetters[] = { + { + "installsizechange", + (getter)Transaction_get_installsizechange, + NULL, + NULL, + NULL + }, + { NULL }, +}; PyTypeObject TransactionType = { PyVarObject_HEAD_INIT(NULL, 0) - tp_name: "_pakfire.Transaction", - tp_basicsize: sizeof(TransactionObject), - tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - tp_new : Transaction_new, - tp_dealloc: (destructor) Transaction_dealloc, - tp_doc: "Sat Transaction objects", + tp_name: "_pakfire.Transaction", + tp_basicsize: sizeof(TransactionObject), + tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + tp_new: Transaction_new, + tp_dealloc: (destructor)Transaction_dealloc, + tp_init: (initproc)Transaction_init, + tp_doc: "Transaction object", + tp_getset: Transaction_getsetters, + tp_iter: (getiterfunc)Transaction_iter, }; -PyObject* Transaction_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - TransactionObject *self; - SolverObject *solver; +static PyObject* TransactionIterator_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { + TransactionIteratorObject* self = (TransactionIteratorObject *)type->tp_alloc(type, 0); - if (!PyArg_ParseTuple(args, "O", &solver)) { - /* XXX raise exception */ - } - - self = (TransactionObject *)type->tp_alloc(type, 0); - if (self != NULL) { - self->_pool = solver->_solver->pool; - if (self->_pool == NULL) { - Py_DECREF(self); - return NULL; - } - - // Create a new transaction from the solver and order it. - self->_transaction = solver_create_transaction(solver->_solver); - transaction_order(self->_transaction, 0); + if (self) { + self->transaction = NULL; + self->iterator = 0; } return (PyObject *)self; } -PyObject *Transaction_dealloc(TransactionObject *self) { - /* XXX need to free self->_transaction */ - Py_TYPE(self)->tp_free((PyObject *)self); +static void TransactionIterator_dealloc(TransactionIteratorObject* self) { + Py_XDECREF(self->transaction); - Py_RETURN_NONE; + Py_TYPE(self)->tp_free((PyObject *)self); } -PyObject *Transaction_steps(TransactionObject *self, PyObject *args) { - PyObject *list = PyList_New(0); +static int TransactionIterator_init(TransactionIteratorObject* self, PyObject* args, PyObject* kwds) { + TransactionObject* transaction; - StepObject *step; - int i = 0; - for(; i < self->_transaction->steps.count; i++) { - step = PyObject_New(StepObject, &StepType); - step->_transaction = self->_transaction; - step->_id = self->_transaction->steps.elements[i]; + if (!PyArg_ParseTuple(args, "O!", &TransactionType, &transaction)) + return -1; - PyList_Append(list, (PyObject *)step); - } + self->transaction = transaction; + Py_INCREF(self->transaction); - return list; + return 0; } -PyObject *Transaction_get_installsizechange(TransactionObject *self) { - int installsizechange = transaction_calc_installsizechange(self->_transaction); +static PyObject* TransactionIterator_next(TransactionIteratorObject* self) { + PakfireStep step = pakfire_transaction_get_step(self->transaction->transaction, self->iterator++); + if (step) + return new_step(self->transaction, step); - return Py_BuildValue("i", installsizechange * 1024); + return NULL; } + +PyTypeObject TransactionIteratorType = { + PyVarObject_HEAD_INIT(NULL, 0) + tp_name: "_pakfire.TransactionIterator", + tp_basicsize: sizeof(TransactionIteratorObject), + tp_flags: Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + tp_new: TransactionIterator_new, + tp_dealloc: (destructor)TransactionIterator_dealloc, + tp_init: (initproc)TransactionIterator_init, + tp_doc: "TransactionIterator object", + tp_iternext: (iternextfunc)TransactionIterator_next, +}; diff --git a/src/_pakfire/transaction.h b/src/_pakfire/transaction.h index 7c5c1cc8f..314b8dd59 100644 --- a/src/_pakfire/transaction.h +++ b/src/_pakfire/transaction.h @@ -23,20 +23,27 @@ #include -#include +#include + +#include "request.h" -// Sat Transaction object typedef struct { - PyObject_HEAD - Pool *_pool; - Transaction *_transaction; + PyObject_HEAD + RequestObject* request; + PakfireTransaction transaction; } TransactionObject; -extern PyObject* Transaction_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -extern PyObject *Transaction_dealloc(TransactionObject *self); -extern PyObject *Transaction_steps(TransactionObject *self, PyObject *args); -extern PyObject *Transaction_get_installsizechange(TransactionObject *self); - extern PyTypeObject TransactionType; +typedef struct { + PyObject_HEAD + TransactionObject* transaction; + int iterator; +} TransactionIteratorObject; + +extern PyTypeObject TransactionIteratorType; + +PyObject* new_transaction(RequestObject* request, PakfireTransaction trans); +PyObject* new_transaction_iterator(TransactionObject* transaction); + #endif /* PYTHON_PAKFIRE_TRANSACTION_H */