8000 GitHub - patricknevindwyer/PredicateUtility: Utility classes and wrappers for working with NSPredicates and NSPredicateEditors from Python
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

patricknevindwyer/PredicateUtility

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

About

PredicateUtility is a small collection of classes for efficient and easy management of NSPredicateEditors and NSPredicates when creating Cocoa apps with Python. These classes rely upon the PyObjC bridge.

These classes arose out of a need to generate SQL WHERE clauses from NSPredicates; a task that is handled automatically when using Cocoa and CoreData bindings, but unavailable when using non-managed databases.

The following classes are defined in PredicateUtility:

  • PredicateEditorManager - Configure and control a NSPredicateEditor
  • PredicateWrapper - Deconstruct an NSPredicate (or subclass) into a SQL snippit
  • PredicateError - General purpose Exception when working with PredicateUtility classes

Example Application

The Example 01 application is a barebones NSApplication based app that generates SQL snippits from aribitrarily nested NSPredicates taken from an NSPredicateEditor. You can nest NSPredicateEditor rows by holding the option key while clicking on the + button of an NSPredicateEditor row.

Terminology

The PredicateUtility classes use the terminology column and criteria when describing configuring, displaying, and deconstructing NSPredicate objects. In this context column refers to a SQL column name, such as "column1". It is assumed that the column name is a valid SQL identifier. The criteria refer to how a column is configured to be queried in an NSPredicateEditor, and includes the operators that can be used, and the type of the column (currently PredicateUtility only supports an implicit "string" type).

How To

PredicateEditorManager and PredicateWrapper

Given an IBOutlet linked to an NSPredicateEditor, the following code in the Application Delegate creates the PredicateEditorManager, configures the columns to be used in the PredicateEditor, sets up the UI, and generates SQL when a button callback is triggered:

from Foundation import *
from AppKit import *
from objc import IBOutlet, IBAction

from PredicateUtility import *

class Example01AppDelegate(NSObject):

	editor = IBOutlet()
	
	def applicationDidFinishLaunching_(self, sender):
		
		# create the editor
		self.predicateManager = PredicateEditorManager.alloc().initWithPredicateEditor_(self.editor)

		# add a few search criteria
		self.predicateManager.addMappedCriteria("First Name", "firstname", operators = [PredicateEditorManager.OP_EQ, PredicateEditorManager.OP_BEGINSWITH])
		self.predicateManager.addMappedCriteria("Last Name", "lastname", operators = [PredicateEditorManager.OP_NE, PredicateEditorManager.OP_CONTAINS])
		self.predicateManager.addCriteria("zipcode")
		
		# build the predicate manager
		self.predicateManager.build()
		self.predicateManager.addRow()
		
	@IBAction
	def generateSQL_(self, id):
		print "sql: ", self.predicateManager.wrappedPredicate().toSQL() 

There are a few things going on in this example. Firstly, the PredicateEditorManager is created, using the initWithPredicateEditor_ initializer. Once the PredicateEditorManager has been created, columns, or criteria for searching and building a predicate, can be added. In some cases the column for the search is a simple name, like zipcode, which can be used in sql as a column name, and is easily understood in the UI by a user. In this case the addCriteria method can be used:

self.predicateManager.addCriteria("zipcode")

The types of operators to use in comparing the zipcode criteria could have been optionally included as a named parameter:

self.predicateManager.addCriteria("zipcode", operators = [PredicateEditorManager.OP_EQ, PredicateEditorManager.OP_NE])

In some cases the SQL column name is hard to understand, or a localized or "nice" version of the column name is know. An alternate method can be used to configure a criteria with a display name different from it's SQL name:

self.predicateManager.addMappedCriteria("First Name", "firstname", operators = [PredicateEditorManager.OP_EQ, PredicateEditorManager.OP_BEGINSWITH])

Here the SQL column firstname will be displayed in the UI as First Name, but SQL generated from the PredicateWrapper will contain the proper firstname column name.

The following operators are currently supported (with the Cocoa equivalent type in parenthesis):

  • OP_EQ (NSEqualToPredicateOperatorType) - column equal to
  • OP_NE (NSNotEqualToPredicateOperatorType) - column not equal to
  • OP_CONTAINS (NSContainsPredicateOperatorType) - column contains value
  • OP_BEGINSWITH (NSBeginsWithPredicateOperatorType) - column begins with
  • OP_ENDSWITH (NSEndsWithPredicateOperatorType) - column ends with

Just PredicateWrapper

It is also possible to use the PredicateWrapper directly without needing an PredicateEditorWrapper. If you have an NSPredicate object (or subclass), you can convert it to SQL with a PredicateWrapper:

predicate = <get an NSCompoundPredicate from somewhere>
wrapper = PredicateWrapper(predicate)
print wrapper.toSQL()

Because criteria are never specified it is not possible to use mapped column names in this instance.

Limitations

So far these classes only support the most basic features of NSPredicates and NSPredicateEditor. The only data type that can be used in the NSPredicateEditor is the String type.

Incremental improvements will be made to these classes as needed; or if you have a feature you'd like to see sooner rather than later, please contact me.

License & Contact

PredicateUtility and the included sample applications are released under an Apache 2.0 license.

If you have questions, comments, or issues, please contact me patricknevindwyer(@)gmail.com

About

Utility classes and wrappers for working with NSPredicates and NSPredicateEditors from Python

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
0