aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Richard Brown <rbrown@exherbo.org> 2007-02-10 12:43:24 +0000
committerAvatar Richard Brown <rbrown@exherbo.org> 2007-02-10 12:43:24 +0000
commit2502195e185d4b622e49b22fede038c55e024b47 (patch)
tree9487adf02b06dff3180dcaae9cdb6324c7b39150
parente5fa14e3abf4178270e9e4c4e3d27959cabcfeb2 (diff)
downloadpaludis-2502195e185d4b622e49b22fede038c55e024b47.tar.gz
paludis-2502195e185d4b622e49b22fede038c55e024b47.tar.xz
Add new Query to ruby binding.
-rw-r--r--ruby/Makefile.am6
-rw-r--r--ruby/package_database.cc35
-rw-r--r--ruby/package_database_TEST.rb17
-rw-r--r--ruby/paludis_ruby.hh4
-rw-r--r--ruby/query.cc220
-rw-r--r--ruby/query_TEST.rb165
6 files changed, 432 insertions, 15 deletions
diff --git a/ruby/Makefile.am b/ruby/Makefile.am
index 3799cee..5fb4735 100644
--- a/ruby/Makefile.am
+++ b/ruby/Makefile.am
@@ -30,7 +30,8 @@ IF_RUBY_TESTS = \
qualified_package_name_TEST.rb \
contents_TEST.rb \
dep_list_TEST.rb \
- dep_tag_TEST.rb
+ dep_tag_TEST.rb \
+ query_TEST.rb
IF_RUBY_QA_TESTS = \
message_TEST.rb \
@@ -54,7 +55,8 @@ IF_RUBY_SOURCES = \
qualified_package_name.cc \
contents.cc \
dep_list.cc \
- dep_tag.cc
+ dep_tag.cc \
+ query.cc
IF_RUBY_QA_SOURCES = \
message.cc \
diff --git a/ruby/package_database.cc b/ruby/package_database.cc
index df33ff3..d090c2c 100644
--- a/ruby/package_database.cc
+++ b/ruby/package_database.cc
@@ -78,16 +78,29 @@ namespace
/*
* call-seq:
+ * query(query, query_order) -> Array
* query(atom, install_state, query_order) -> Array
*
- * Query the repositoty. Returns an array of PackageDatabaseEntry
+ * Query the repository, the first argument is either a PackageDepAtom or a Query.
+ * Returns an array of PackageDatabaseEntry.
*/
VALUE
package_database_query(int argc, VALUE *argv, VALUE self)
{
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> items;
try
{
- if (2 == argc || 3 == argc)
+ if (2 == argc && is_kind_of_query(argv[0]))
+ {
+ Query q = value_to_query(argv[0]);
+ QueryOrder qo = static_cast<QueryOrder>(NUM2INT(argv[1]));
+
+ std::tr1::shared_ptr<PackageDatabase> * self_ptr;
+ Data_Get_Struct(self, std::tr1::shared_ptr<PackageDatabase>, self_ptr);
+
+ items = ((*self_ptr)->query(q, qo));
+ }
+ else if (2 == argc || 3 == argc)
{
QueryOrder qo;
std::tr1::shared_ptr<const PackageDepAtom> pda(value_to_package_dep_atom(argv[0]));
@@ -95,7 +108,7 @@ namespace
if (2 ==argc)
{
qo = qo_order_by_version;
- rb_warn("Calling query with two arguments has been deprecated");
+ rb_warn("Calling query with (PackageDepAtom, InstallState) has been deprecated");
}
else
qo = static_cast<QueryOrder>(NUM2INT(argv[2]));
@@ -103,25 +116,23 @@ namespace
std::tr1::shared_ptr<PackageDatabase> * self_ptr;
Data_Get_Struct(self, std::tr1::shared_ptr<PackageDatabase>, self_ptr);
- std::tr1::shared_ptr<const PackageDatabaseEntryCollection> items((*self_ptr)->query(
- *pda, is, qo
- ));
+ items = ((*self_ptr)->query(*pda, is, qo));
- VALUE result(rb_ary_new());
- for (PackageDatabaseEntryCollection::Iterator i(items->begin()),
- i_end(items->end()) ; i != i_end ; ++i)
- rb_ary_push(result, package_database_entry_to_value(*i));
- return result;
}
else
{
- rb_raise(rb_eArgError, "query expects three arguments, but got %d",argc);
+ rb_raise(rb_eArgError, "query expects two or three arguments, but got %d",argc);
}
}
catch (const std::exception & e)
{
exception_to_ruby_exception(e);
}
+ VALUE result(rb_ary_new());
+ for (PackageDatabaseEntryCollection::Iterator i(items->begin()),
+ i_end(items->end()) ; i != i_end ; ++i)
+ rb_ary_push(result, package_database_entry_to_value(*i));
+ return result;
}
/*
diff --git a/ruby/package_database_TEST.rb b/ruby/package_database_TEST.rb
index 907da87..35f97a0 100644
--- a/ruby/package_database_TEST.rb
+++ b/ruby/package_database_TEST.rb
@@ -78,6 +78,10 @@ module Paludis
db.query(PackageDepAtom.new("=foo/bar-1.0"), InstallState::Any, QueryOrder::Whatever)
end
+ assert_nothing_raised do
+ db.query(Query::Matches.new(PackageDepAtom.new('=foo/bar-1.0')), QueryOrder::Whatever)
+ end
+
assert_raise ArgumentError do
db.query(1,2,3,4);
end
@@ -87,13 +91,24 @@ module Paludis
a = db.query("=foo/bar-1.0", InstallState::InstallableOnly, QueryOrder::Whatever)
assert_equal a, [ PackageDatabaseEntry.new("foo/bar", "1.0", "testrepo") ]
+ a = db.query(Query::Matches.new('=foo/bar-1.0') & Query::RepositoryHasInstallableInterface.new,
+ QueryOrder::Whatever)
+ assert_equal a, [ PackageDatabaseEntry.new("foo/bar", "1.0", "testrepo") ]
+
a = db.query(PackageDepAtom.new("=foo/bar-1.0"), InstallState::Any, QueryOrder::Whatever)
assert_equal a, [ PackageDatabaseEntry.new("foo/bar", "1.0", "testrepo") ]
a = db.query("foo/bar", InstallState::InstallableOnly, QueryOrder::OrderByVersion)
assert_equal a, [
PackageDatabaseEntry.new("foo/bar", "1.0", "testrepo"),
- PackageDatabaseEntry.new("foo/bar", "2.0", "testrepo") ]
+ PackageDatabaseEntry.new("foo/bar", "2.0", "testrepo")
+ ]
+
+ a = db.query(Query::Package.new('foo/bar'), QueryOrder::OrderByVersion)
+ assert_equal a, [
+ PackageDatabaseEntry.new("foo/bar", "1.0", "testrepo"),
+ PackageDatabaseEntry.new("foo/bar", "2.0", "testrepo")
+ ]
a = db.query(">=foo/bar-27", InstallState::InstallableOnly, QueryOrder::Whatever)
assert a.empty?
diff --git a/ruby/paludis_ruby.hh b/ruby/paludis_ruby.hh
index 9404507..f684d73 100644
--- a/ruby/paludis_ruby.hh
+++ b/ruby/paludis_ruby.hh
@@ -34,6 +34,7 @@
#include <paludis/environment.hh>
#include <paludis/environment/no_config/no_config_environment.hh>
#include <paludis/repositories/portage/portage_repository.hh>
+#include <paludis/query.hh>
#ifdef ENABLE_RUBY_QA
#include <paludis/qa/qa.hh>
@@ -76,6 +77,8 @@ namespace paludis
VALUE environment_class();
VALUE no_config_environment_class();
+ bool is_kind_of_query(VALUE query);
+
/* constructors */
VALUE mask_reasons_to_value(const MaskReasons &);
@@ -101,6 +104,7 @@ namespace paludis
NoConfigEnvironment* value_to_no_config_environment(VALUE v);
PortageRepositoryProfilesDescLine value_to_portage_repository_profiles_desc_line(VALUE v);
MaskReasons value_to_mask_reasons(VALUE v);
+ Query value_to_query(VALUE v);
#ifdef ENABLE_RUBY_QA
VALUE paludis_qa_module();
diff --git a/ruby/query.cc b/ruby/query.cc
new file mode 100644
index 0000000..2675005
--- /dev/null
+++ b/ruby/query.cc
@@ -0,0 +1,220 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Richard Brown <mynamewasgone@gmail.com>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis_ruby.hh>
+#include <paludis/util/log.hh>
+#include <paludis/query.hh>
+#include <ruby.h>
+
+using namespace paludis;
+using namespace paludis::ruby;
+
+#define RUBY_FUNC_CAST(x) reinterpret_cast<VALUE (*)(...)>(x)
+
+namespace
+{
+ static VALUE c_query_module;
+ static VALUE c_query;
+ static VALUE c_matches;
+ static VALUE c_package;
+ static VALUE c_not_masked;
+ static VALUE c_repository_has_installed_interface;
+ static VALUE c_repository_has_installable_interface;
+ static VALUE c_repository_has_uninstallable_interface;
+
+ VALUE
+ query_to_value(const Query & v)
+ {
+ Query * vv(new Query(v));
+ return Data_Wrap_Struct(c_query, 0, &Common<Query>::free, vv);
+ }
+
+ VALUE
+ query_init(int, VALUE *, VALUE self)
+ {
+ return self;
+ }
+
+ /*
+ * Document-method: &
+ *
+ * call-seq:
+ * &(other_query) -> Query
+ *
+ * Combine Queries
+ */
+ VALUE
+ query_and(VALUE self, VALUE other)
+ {
+ Query * ptr;
+ Data_Get_Struct(self, Query, ptr);
+ try
+ {
+ return query_to_value((*ptr) & value_to_query(other));
+ }
+ catch (const std::exception & e)
+ {
+ exception_to_ruby_exception(e);
+ }
+ }
+
+ /*
+ * call-seq:
+ * Matches.new(pda)
+ *
+ * Create a new Matches Query object from the given PackageDepAtom.
+ */
+ VALUE
+ matches_new(VALUE self, VALUE pda)
+ {
+ query::Matches * ptr(0);
+ try
+ {
+ ptr = new query::Matches(*value_to_package_dep_atom(pda));
+ VALUE tdata(Data_Wrap_Struct(self, 0, &Common<query::Matches>::free, ptr));
+ rb_obj_call_init(tdata, 1, &pda);
+ return tdata;
+
+ }
+ catch (const std::exception & e)
+ {
+ delete ptr;
+ exception_to_ruby_exception(e);
+ }
+ }
+
+ /*
+ * call-seq:
+ * Package.new(qpn)
+ *
+ * Create a new Package Query object from the given QualifiedPackageName.
+ */
+ VALUE
+ package_new(VALUE self, VALUE qpn)
+ {
+ query::Package * ptr(0);
+ try
+ {
+ ptr = new query::Package(value_to_qualified_package_name(qpn));
+ VALUE tdata(Data_Wrap_Struct(self, 0, &Common<query::Package>::free, ptr));
+ rb_obj_call_init(tdata, 1, &qpn);
+ return tdata;
+
+ }
+ catch (const std::exception & e)
+ {
+ delete ptr;
+ exception_to_ruby_exception(e);
+ }
+ }
+
+ template <typename A_>
+ struct QueryNew
+ {
+ static VALUE
+ query_new(VALUE self)
+ {
+ A_ * ptr = new A_();
+ VALUE tdata(Data_Wrap_Struct(self, 0, &Common<A_>::free, ptr));
+ rb_obj_call_init(tdata, 0, 0);
+ return tdata;
+ }
+ };
+
+ void do_register_query()
+ {
+ /*
+ * Document-module: Paludis::Query
+ *
+ * Collection of classes for use in querying package databases
+ */
+ c_query_module = rb_define_module_under(paludis_module(), "Query");
+
+ /*
+ * Document-class: Paludis::Query::Query
+ *
+ * Base query class.
+ */
+ c_query = rb_define_class_under(c_query_module, "Query", rb_cObject);
+ rb_funcall(c_query, rb_intern("private_class_method"), 1, rb_str_new2("new"));
+ rb_define_method(c_query, "initialize", RUBY_FUNC_CAST(&query_init), -1);
+ rb_define_method(c_query, "&", RUBY_FUNC_CAST(&query_and), 1);
+
+ /*
+ * Document-class: Paludis::Query::Matches
+ *
+ * Query for packages that match a PackageDepAtom
+ */
+ c_matches = rb_define_class_under(c_query_module, "Matches", c_query);
+ rb_define_singleton_method(c_matches, "new", RUBY_FUNC_CAST(&matches_new), 1);
+
+ /*
+ * Document-class: Paludis::Query::Package
+ *
+ * Query for packages that match a QualifiedPackageName
+ */
+ c_package = rb_define_class_under(c_query_module, "Package", c_query);
+ rb_define_singleton_method(c_package, "new", RUBY_FUNC_CAST(&package_new), 1);
+
+ c_not_masked = rb_define_class_under(c_query_module, "NotMasked", c_query);
+ rb_define_singleton_method(c_not_masked, "new",
+ RUBY_FUNC_CAST(&QueryNew<query::NotMasked>::query_new), 0);
+
+ c_repository_has_installed_interface = rb_define_class_under(c_query_module,
+ "RepositoryHasInstalledInterface", c_query);
+ rb_define_singleton_method(c_repository_has_installed_interface, "new",
+ RUBY_FUNC_CAST(&QueryNew<query::RepositoryHasInstalledInterface>::query_new), 0);
+
+ c_repository_has_installable_interface = rb_define_class_under(c_query_module,
+ "RepositoryHasInstallableInterface", c_query);
+ rb_define_singleton_method(c_repository_has_installable_interface, "new",
+ RUBY_FUNC_CAST(&QueryNew<query::RepositoryHasInstallableInterface>::query_new), 0);
+
+ c_repository_has_uninstallable_interface = rb_define_class_under(c_query_module,
+ "RepositoryHasUninstallableInterface", c_query);
+ rb_define_singleton_method(c_repository_has_uninstallable_interface, "new",
+ RUBY_FUNC_CAST(&QueryNew<query::RepositoryHasUninstallableInterface>::query_new), 0);
+ }
+}
+
+Query
+paludis::ruby::value_to_query(VALUE v)
+{
+ if (rb_obj_is_kind_of(v, c_query))
+ {
+ Query * v_ptr;
+ Data_Get_Struct(v, Query, v_ptr);
+ return *v_ptr;
+ }
+ else
+ {
+ rb_raise(rb_eTypeError, "Can't convert %s into Query", rb_obj_classname(v));
+ }
+}
+
+bool
+paludis::ruby::is_kind_of_query(VALUE v)
+{
+ return rb_obj_is_kind_of(v, c_query);
+}
+
+
+RegisterRubyClass::Register paludis_ruby_register_query PALUDIS_ATTRIBUTE((used)) (&do_register_query);
+
+
diff --git a/ruby/query_TEST.rb b/ruby/query_TEST.rb
new file mode 100644
index 0000000..57cb303
--- /dev/null
+++ b/ruby/query_TEST.rb
@@ -0,0 +1,165 @@
+#!/usr/bin/env ruby
+# vim: set sw=4 sts=4 et tw=80 :
+
+#
+# Copyright (c) 2007 Richard Brown <mynamewasgone@gmail.com>
+#
+# This file is part of the Paludis package manager. Paludis is free software;
+# you can redistribute it and/or modify it under the terms of the GNU General
+# Public License version 2, as published by the Free Software Foundation.
+#
+# Paludis 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, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+require 'test/unit'
+require 'Paludis'
+
+module Paludis
+ class TestCase_Query < Test::Unit::TestCase
+ def test_no_create
+ assert_raise NoMethodError do
+ Query::Query.new;
+ end
+ end
+ end
+
+ class TestCase_RepositoryHasInstallableInterface < Test::Unit::TestCase
+ def get_query
+ Query::RepositoryHasInstallableInterface.new
+ end
+
+ def test_create
+ assert_nothing_raised do
+ get_query
+ end
+ end
+
+ def test_and
+ q = get_query
+ assert_respond_to q, :&
+ assert_kind_of Query::Query, q & q
+ end
+
+ def test_kind_of
+ assert_kind_of Query::Query, get_query
+ end
+ end
+
+ class TestCase_RepositoryHasUninstallableInterface < Test::Unit::TestCase
+ def get_query
+ Query::RepositoryHasUninstallableInterface.new
+ end
+
+ def test_create
+ assert_nothing_raised do
+ get_query
+ end
+ end
+
+ def test_and
+ q = get_query
+ assert_respond_to q, :&
+ assert_kind_of Query::Query, q & q
+ end
+
+ def test_kind_of
+ assert_kind_of Query::Query, get_query
+ end
+ end
+
+ class TestCase_RepositoryHasInstalledInterface < Test::Unit::TestCase
+ def get_query
+ Query::RepositoryHasInstalledInterface.new
+ end
+
+ def test_create
+ assert_nothing_raised do
+ get_query
+ end
+ end
+
+ def test_and
+ q = get_query
+ assert_respond_to q, :&
+ assert_kind_of Query::Query, q & q
+ end
+
+ def test_kind_of
+ assert_kind_of Query::Query, get_query
+ end
+ end
+
+ class TestCase_NotMasked < Test::Unit::TestCase
+ def get_query
+ Query::NotMasked.new
+ end
+
+ def test_create
+ assert_nothing_raised do
+ get_query
+ end
+ end
+
+ def test_and
+ q = get_query
+ assert_respond_to q, :&
+ assert_kind_of Query::Query, q & q
+ end
+
+ def test_kind_of
+ assert_kind_of Query::Query, get_query
+ end
+ end
+
+ class TestCase_Matches < Test::Unit::TestCase
+ def get_query
+ Query::Matches.new(PackageDepAtom.new('>=foo-bar/baz-1'))
+ end
+
+ def test_create
+ assert_nothing_raised do
+ get_query
+ end
+ end
+
+ def test_and
+ q = get_query
+ assert_respond_to q, :&
+ assert_kind_of Query::Query, q & q
+ end
+
+ def test_kind_of
+ assert_kind_of Query::Query, get_query
+ end
+ end
+
+ class TestCase_Package < Test::Unit::TestCase
+ def get_query
+ Query::Package.new(QualifiedPackageName.new('foo-bar/baz'))
+ end
+
+ def test_create
+ assert_nothing_raised do
+ get_query
+ end
+ end
+
+ def test_and
+ q = get_query
+ assert_respond_to q, :&
+ assert_kind_of Query::Query, q & q
+ end
+
+ def test_kind_of
+ assert_kind_of Query::Query, get_query
+ end
+ end
+end
+