Michael Granger avatar Michael Granger committed bce4b3b

Add the beginning of the OpenLDAP::Result class.

Comments (0)

Files changed (6)

ext/openldap_ext/connection.c

 /*
  * Fetch the data pointer and check it for sanity.
  */
-static struct ropenldap_connection *
+struct ropenldap_connection *
 ropenldap_get_conn( VALUE self )
 {
 	struct ropenldap_connection *conn = check_conn( self );

ext/openldap_ext/openldap.h

 extern VALUE ropenldap_mOpenLDAP;
 
 extern VALUE ropenldap_cOpenLDAPConnection;
+extern VALUE ropenldap_cOpenLDAPResult;
 
 extern VALUE ropenldap_eOpenLDAPError;
 
     LDAP    *ldap;
 };
 
+/* OpenLDAP::Result struct */
+struct ropenldap_result {
+	LDAP        *ldap;
+	int         msgid;
+	LDAPMessage *message;
+	VALUE       connection;
+	VALUE       abandoned;
+};
 
 /* --------------------------------------------------------------
  * Macros
  * -------------------------------------------------------------- */
 #define IsConnection( obj ) rb_obj_is_kind_of( (obj), ropenldap_cOpenLDAPConnection )
+#define IsResult( obj ) rb_obj_is_kind_of( (obj), ropenldap_cOpenLDAPResult )
 
 #ifdef UNUSED
 #elif defined(__GNUC__)
 
 void Init_openldap_ext                  _(( void ));
 void ropenldap_init_connection          _(( void ));
+void ropenldap_init_result              _(( void ));
+
+struct ropenldap_connection *ropenldap_get_conn _(( VALUE ));
 
 
 #endif /* __OPENLDAP_H__ */

ext/openldap_ext/result.c

+/*
+ * Ruby-OpenLDAP -- OpenLDAP::Result class
+ * $Id$
+ *
+ * Authors
+ *
+ * - Michael Granger <ged@FaerieMUD.org>
+ *
+ * Copyright (c) 2011 Michael Granger
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice, this
+ *    list of conditions and the following disclaimer in the documentation and/or
+ *    other materials provided with the distribution.
+ *
+ *  * Neither the name of the authors, nor the names of its contributors may be used to
+ *    endorse or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+
+#include "openldap.h"
+
+
+
+/* --------------------------------------------------------------
+ * Declarations
+ * -------------------------------------------------------------- */
+VALUE ropenldap_cOpenLDAPResult;
+
+
+/* --------------------------------------------------
+ *	Memory-management functions
+ * -------------------------------------------------- */
+
+/*
+ * Allocation function
+ */
+static struct ropenldap_result *
+ropenldap_result_alloc( VALUE connection, int msgid )
+{
+	struct ropenldap_result *ptr = ALLOC( struct ropenldap_result );
+	struct ropenldap_connection *conn = ropenldap_get_conn( connection );
+
+	ptr->ldap       = conn->ldap;
+	ptr->msgid      = FIX2INT( msgid );
+	ptr->message    = NULL;
+	ptr->connection = connection;
+	ptr->abandoned  = Qfalse;
+
+	return ptr;
+}
+
+
+/*
+ * GC Mark function
+ */
+static void
+ropenldap_result_gc_mark( struct ropenldap_result *ptr )
+{
+	if ( ptr ) {
+		rb_gc_mark( ptr->connection );
+	}
+}
+
+
+
+/*
+ * GC Free function
+ */
+static void
+ropenldap_result_gc_free( struct ropenldap_result *ptr )
+{
+	if ( ptr ) {
+		ptr->ldap       = NULL;
+		ptr->msgid      = 0;
+		ptr->message    = NULL;
+		ptr->connection = Qnil;
+		ptr->abandoned  = Qfalse;
+
+		xfree( ptr );
+		ptr = NULL;
+	}
+}
+
+
+/*
+ * Object validity checker. Returns the data pointer.
+ */
+static struct ropenldap_result *
+check_result( VALUE self )
+{
+	Check_Type( self, T_DATA );
+
+    if ( !IsResult(self) ) {
+		rb_raise( rb_eTypeError, "wrong argument type %s (expected an OpenLDAP::Result)",
+				  rb_obj_classname( self ) );
+    }
+
+	return DATA_PTR( self );
+}
+
+
+/*
+ * Fetch the data pointer and check it for sanity.
+ */
+static struct ropenldap_result *
+ropenldap_get_result( VALUE self )
+{
+	struct ropenldap_result *conn = check_result( self );
+
+	if ( !conn ) rb_fatal( "Use of uninitialized OpenLDAP::Result" );
+
+	return conn;
+}
+
+
+
+/* --------------------------------------------------------------
+ * Class methods
+ * -------------------------------------------------------------- */
+
+/*
+ * call-seq:
+ *    OpenLDAP::Result.allocate   -> store
+ *
+ * Allocate a new OpenLDAP::Result object.
+ *
+ */
+static VALUE
+ropenldap_result_s_allocate( VALUE klass )
+{
+	return Data_Wrap_Struct( klass, ropenldap_result_gc_mark, ropenldap_result_gc_free, 0 );
+}
+
+
+/* --------------------------------------------------------------
+ * Instance methods
+ * -------------------------------------------------------------- */
+
+/*
+ * call-seq:
+ *    OpenLDAP::Result.new( connection, msgid )    -> result
+ *
+ * Create a new OpenLDAP::Result object for the specified +msgid+ on the given
+ * +connection+.
+ *
+ */
+static VALUE
+ropenldap_result_initialize( VALUE self, VALUE connection, VALUE msgid )
+{
+	ropenldap_log_obj( self, "debug", "Initializing 0x%x", self );
+
+	if ( !check_result(self) ) {
+		DATA_PTR( self ) = ropenldap_result_alloc( connection, NUM2INT(msgid) );
+	} else {
+		rb_raise( ropenldap_eOpenLDAPError,
+				  "Cannot re-initialize a result once it's been created." );
+	}
+
+	return Qnil;
+}
+
+
+/*
+ * call-seq:
+ *    abandon   -> true
+ *
+ * Abandon the operation in progress and discard any results that have been
+ * queued.
+ *
+ */
+static VALUE
+ropenldap_result_abandon( int argc, VALUE *argv, VALUE self )
+{
+	struct ropenldap_result *ptr = ropenldap_get_result( self );
+	int res;
+
+	/* :TODO: controls */
+
+	res = ldap_abandon_ext( ptr->ldap, ptr->msgid, NULL, NULL );
+	ropenldap_check_result( res, "ldap_abandon_ext" );
+
+	return Qtrue;
+}
+
+
+
+
+/*
+ * document-class: OpenLDAP::Result
+ */
+void
+ropenldap_init_result( void )
+{
+	ropenldap_log( "debug", "Initializing OpenLDAP::Result" );
+
+#ifdef FOR_RDOC
+	ropenldap_mOpenLDAP = rb_define_module( "OpenLDAP" );
+#endif
+
+	/* OpenLDAP::Result */
+	ropenldap_cOpenLDAPResult =
+		rb_define_class_under( ropenldap_mOpenLDAP, "Result", rb_cObject );
+
+	rb_define_alloc_func( ropenldap_cOpenLDAPResult, ropenldap_result_s_allocate );
+
+	rb_define_protected_method( ropenldap_cOpenLDAPResult, "initialize",
+	                            ropenldap_result_initialize, 2 );
+
+	rb_define_method( ropenldap_cOpenLDAPResult, "abandon", ropenldap_result_abandon, -1 );
+
+	rb_require( "openldap/result" );
+}
+
 	end
 
 
+
+	### Create a new Connection object.
+	###
+	### :call-seq:
+	###   OpenLDAP.connection                      -> connection
+	###   OpenLDAP.connection( ldapurl )           -> connection
+	###   OpenLDAP.connection( host, port=389 )    -> connection
+	###
+	### If no argument is given, the defaults are used (OpenLDAP.uris).
+	def self::connection( *args )
+		case args.first
+		when NilClass
+			self.log.info "Connecting using defaults: %p" % [ self.uris ]
+			return OpenLDAP::Connection.new( self.uris.join(' ') )
+		when URI, /^ldap(i|s)?:/i
+			self.log.info "Connecting using an LDAP URL: %p" % [ args.first ]
+			return OpenLDAP::Connection.new( args.join(' ') )
+		else
+			self.log.info "Connecting using host/port" % [ args ]
+			uri = "ldap://%s:%d" % [ args.first, args[1] || 389 ]
+			return OpenLDAP::Connection.new( uri )
+		end
+	end
+
+
 	### Load the extension
 	begin
 		require 'openldap_ext'
 
 	end
 
+
 	# Load the remaining Ruby parts of the library
 	require 'openldap/exceptions'
 

lib/openldap/result.rb

+# -*- ruby -*-
+#encoding: utf-8
+
+require 'uri'
+require 'openldap' unless defined?( OpenLDAP )
+
+# OpenLDAP Result class
+class OpenLDAP::Result
+	extend Loggability
+
+	# Loggability API -- log to the openldap logger.
+	log_to :openldap
+
+end # class OpenLDAP::Result
+
+

spec/openldap/result_spec.rb

+#!/usr/bin/env rspec -cfd -b
+
+BEGIN {
+	require 'pathname'
+	basedir = Pathname( __FILE__ ).dirname.parent.parent
+	libdir = basedir + 'lib'
+
+	$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
+	$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
+}
+
+require 'rspec'
+require 'spec/lib/helpers'
+require 'openldap/result'
+
+describe OpenLDAP::Result do
+
+	before( :all ) do
+		setup_logging( :fatal )
+	end
+
+	before( :each ) do
+		@ldap = OpenLDAP.connect( 'ldap://localhost' )
+	end
+
+	after( :all ) do
+		reset_logging()
+	end
+
+
+	it "can be created with a connection and a message ID" do
+		result = OpenLDAP::Result.new( )
+	end
+
+end
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.