datomic attribute with a colon prefix - datomic

Have 2 queries about datomic attributes.
1. If I know the attribute name (String), how do I check if the attribute is already defined or not in the schema?
2. Based on my experimenting with datomic, I see that datomic treats attributes with colon prefix and without colon prefix same. i.e if we create attributes named "foo" and ":foo", they are one and the same. Is this true? Is this a limitation?
I am using datomic with groovy.Below is the code used to create the attribute. Along with name, other params are input.
static def createAttribute(String name, String type, String description, Connection connection) {
List schema = [[
':db/id': Peer.tempid(':db.part/db'),
':db/ident' : name,
':db/valueType': type,
':db/cardinality': ':db.cardinality/one',
':db/doc': description,
':db.install/_attribute': ':db.part/db'
]]
connection.transact(schema).get()
And the query I use to verify attribute presence is
def attributeFor(String attributeName, Database db) {
db.entity(attributeName).get(':db.install/_attribute')
}
If I call "createAttribute" with "foo" as attribute name and "attributeFor" method ":foo" as attribute name, I get a result. i.e "foo" and ":foo" are treated same.
How can I create and query for attributes with name that contain a colon prefix?

Datomic attribute names are not Strings, they are edn keywords. The prefix colon is required (and always stored, regardless of whether you specify it in code.) The optionality of the colon when working from languages that do not support a name literal (e.g. Java or Groovy) is intended as a convenience.

Related

How to get all groups of members who distinguishedName begins with something

My requirement is to get all the groups of users whose distinguishedName begins with say Auser*.
So, I created a filter in Apache Directory Studio
(&
(objectClass=group)
(member=CN=Auser*)
)
However, to my surprise, this does not return any results. If I change this to a particular user's distinguishedName, I am able to get results
(&
(objectClass=group)
(member=CN=AUser10,OU=Mygrp,DC=domain,DC=com)
)
Am I missing something ?
member has Distinguished-Name-Syntax, and given it's Active Directory you are trying to search, you can't have substring matching as in a normal Directory-String attribute like cn.
Why don't you just reverse your search strategy? Do a subtree search on your domain with filter (&(objectClass=user)(cn=userprefix*)) retrieving attribute memberOf, export to CSV, remove duplicates, done.
Please try this one :
(&
(objectCategory=group)
(name=Auser*)
)
distinguished name is long name containing full path + name. like : CN=Username,OU=internalFolder,OU=parentFolder,DC=domainComponentName,DC=com
For filtering by name just search on the name or other attributes you want like givenName

How do I query an appengine datastore with an email address

I am trying to lookup users in appengine datastore using their email address. I'm using Go.
This code finds no users.
var users []entity.User
q := datastore.NewQuery("users").Filter("AccountEmail =", "email#address.com")
_, err := q.GetAll(c, &users)
If I change the query to lookup the user with the "Id" property instead it works fine.
var users []entity.User
q := datastore.NewQuery("users").Filter("Id", "185804764220139124118")
_, err := q.GetAll(c, &users)
I've confirmed the property name and value for "AccountEmail" is correct. "AccountEmail" It is indexed too.
Is there some special formatting that needs to be done with an email address to get the query to work?
In order to find the user by email (AccountEmail), all of the following conditions must be true. Please check and ensure each "test" passes:
An entity with property name AccountEmail must exists. Don't forget that the property name is case-sensitive. Note that the datastore name and the struct field name may be different, tags can be used to change it, e.g.
AccountEmail string `datastore:"email"`
The property must be indexed. Note that whether a property is indexed may vary from entity to entity, so you may have an entity where AccountEmail is indexed and another one where AccountEmail is not indexed.
AccountEmail must have a type string. I assume this is trivial and is so. But note that it is possible to save a property with the User type which is different from the string type and when you list entities in the Datastore viewer for example, the email will be displayed just like if it would be an email string, but obviously it is different.
To find the user with AccountEmail="email#address.com", the value saved must be "email#address.com" exactly. Lower and upper case letters are different! Spaces (and all whitespace characters) matter! Please check if the saved value is exactly this as you will not see trailing spaces when printed for example, but they will cause a mismatch! Also some unicode characters have the same visual appearance (they look the same) but their unicode codepoint is not the same and will also cause a mismatch.

How to filter null or empty attributes from an Active Directory Query

I am working with a customers Active Directory which has a lot of cruft in it. There are hundreds of Users with empty givenName and sn attributes. I would like to filter any records that have an empty sn or an empty givenName from my query results as those records cannot be processed by my application.
This works as per my requirements but I believe there must be a better way to do it:
(&(objectClass=User)(|(!(!(sn=*))))(!(!(givenName=*)))))
Is there a more clear and concise way to accomplish this with an ldap query?
sn and givenName have as their superior the name attribute, which is of DirectoryString syntax, that is, the syntax is 1.3.6.1.4.1.1466.115.121.1.15. Attributes which are of syntax DirectoryString are not allowed to be null, that is, a DirectoryString is required to have at least one character.
The filter sn=* is a present filter (not a substring or regular expression), meaning that the entry would be filtered out of the possible search results if the sn attribute is not present (if it is present, it must have at least one character). Same for givenName=*.
A simpler filter might be '(&)', where the search request contains the following in its list of attributes to be returned: #User, which will return all attributes in the User objectClass for each entry that matches the filter, then have the application extract the sn and givenName attributes from each entry that is returned. If the number of entries returned is large, use the Simple Paged Results Request Control to throttle the number of entries returned to a more manageable value.
Or ... it might be that Active Directory is not LDAP compliant and does not support the inetOrgPerson objectClass and syntaxes of attributes therein correctly and does allow empty or null attributes values for DirectoryString attributes, though I can't imagine Microsoft would deliver a product that is not LDAP compliant.
see also
LDAP Programming Practices
RFC 4519
(!(!(givenName=*))) = (!givenName=*)
https://technet.microsoft.com/en-us/library/ee198810.aspx

Elementary Apex Object IDs

Quick Question. In the below code, you can see that the for loop (which takes all of the records in newTimecards and puts them as a variable called timecard) and adds the Resource_c to the resourceIds set. I'm confused about how this object is considered an ID data type. When an object is made in Salesforce does it automatically have an ID made, so that it knows Resource_c ID can be added to a set? Note that within the Resource_c Object there is also a field called Resource_ID_c. Resource_c within Timecard_c is a Master-Detail data type. Resource_c is the parent of Timecard_c.
Now that I think about it, resourceIds.add(timecard.Resource_c), does that reference the relationship between the two objects and then searches through Resource_c and adds the ID field Resource_ID_c automactically since it's a unique field?
Thanks for your help.
public class TimecardManager {
public class TimecardException extends Exception {}
public static void handleTimecardChange(List<Timecard__c> oldTimecards,
List<Timecard__c> newTimecards) {
Set<ID> resourceIds = new Set<ID>();
for (Timecard__c timecard : newTimecards) {
resourceIds.add(timecard.Resource__c);
}
Every object instance (and that means EVERY, including factory ones) has a unique organization level ID, whose field name is always Id, is covered by Apex type ID and is a case-sensitive string of 15 characters that also has an 18 character case-insensitive representation. The first three characters are object prefix code (e.g. 500 for a Case) so all instances of the same object share the same prefix. You see these values all across SF (for example in https://na1.salesforce.com/02s7000000BW59L the 02s7000000BW59L in the URL is the ID). When an instance of the object is created using INSERT DML operation, the salesforce automatically assigns unique value based on the prefix and the next available transactional sub ID, it all happens transparently to you.
This is not to be confused with object Name field which is a field you define when you create an object and which can be auto-incremented and so on (e.g. MYOBJ-{00000}) and which can have more meaning to a user than a cryptic ID
When you create a lookup or master-detail relationship it is ID that is being used to link the two instances, not the Name. In the above example Resource__c seems to be that lookup field and it contains Id value of row's master.
What the code does is it enumerates all resources used in timelines and builds a set of their IDs, the purpose of which is most probably to be used via WHERE Id IN :resourceIds clause to load resource details from master table.
mmix's answer is a great overview to what an ID is and where it comes from. To answer what I think is your specific question:
Any time there is a reference from one object to another (like here, between Timecard_c and Resource_c), the field representing the reference will be an ID. So, the for loop that calls resourceIds.add(timecard.Resource__c) is just building up your set of ID's (those 15-character strings). The timecard.Resource__c doesn't look through the Resource__c table to find the ID, timecard.Resource__c is the ID.

LDAP attribute to encode the language of human users mother tongue?

What would be the canonical attribute in an LDAP schema to encode the mother tongue (first language) of a user?
Interop with default/existing administration tools for Windows Active Directory would be a big plus.
The 'preferredLanguage' attribute of the inetOrgPerson (and AD's user) object class is what you are after.
As far as I know this field is not exposed by the default Windows admin tools. You would need a lower-level tool such as adsiedit.msc.
2.7. Preferred Language
Used to indicate an individual's
preferred written or spoken
language. This is useful for
international correspondence or human-
computer interaction. Values for this
attribute type MUST conform to the
definition of the Accept-Language
header field defined in [RFC2068]
with one exception: the sequence
"Accept-Language" ":" should be
omitted. This is a single valued
attribute type.
( 2.16.840.1.113730.3.1.39
NAME 'preferredLanguage'
DESC 'preferred written or spoken language for a person'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
)
RFC 2798 defines the preferredLanguage attribute. Here is its definition from OpenLDAP:
# preferredLanguage
# Used to indicate an individual's preferred written or spoken
# language. This is useful for international correspondence or human-
# computer interaction. Values for this attribute type MUST conform to
# the definition of the Accept-Language header field defined in
# [RFC2068] with one exception: the sequence "Accept-Language" ":"
# should be omitted. This is a single valued attribute type.
attributetype ( 2.16.840.1.113730.3.1.39
NAME 'preferredLanguage'
DESC 'RFC2798: preferred written or spoken language for a person'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )

Resources