Propel ORM with Two FK Columns To Same Foreign Table - mysql

I have a table that contains two foreign keys that map back to a membership table. They are named "from_member" and "to_member."
I am trying to get the Member object that represents this membership table by doing something like:
$feedbackQuery = FeedbackQuery::create()->findOne();
$fromMember = $feedbackQuery->getFromMember();
So that I can go like this:
$firstName = $fromMember->getFirstName();
The only problem is you can't do that, evidently Propel requires you to call $fedbackQuery->getMember()and who knows what that's going to return in this case.
Is there any easy way to accomplish getting the member data like this?

Assuming that you are using from_member_id and to_member_id as your foreign keys, you should have two methods at your disposal. getMemberRelatedByToMemberId() and getMemberRelatedByFromMemberId().
To find your from_member object and to use it.
$fromMember = $feedbackQuery->getMemberRelatedByToMemberId();
$firstname = $fromMember->getFirstName();

Related

Getting another table's string via it's id

I have two tables, but since I can't format them here, you can check the table on this imgur img
The wildcard roles includes strings like department.* or blogger.department.*
I'm trying to create a role/permission inheritance system but i'm stuck on creating a many-to-many relationship
I've tried to use eloquent but since "wildcards" can't be/aren't a model , I can't use eloquent. So I tried to use the DB Facade but I'm not very good with SQL/DB so I've honestly got no clue on how to do this.
Here's what I need
Get the role ID (eg: admin = 1)
Get all wildcard_roles from the table role_wildcards by the Role ID
Return a collection of all the wildcard strings
Notes
It doesn't have to use eloquent, it can use the DB facade
It was actually quite simple after playing around
DB::table('role_wildcards')->where('parent_role_id', $this->id)->get();
Thought it'd be much more complicated
First of you create a relationship from role_wildcards to roles
public function role()
{
return $this->belongsTo('App\roles','parent_role_id','id');
}
then you use relationship like below
DB::table('role_wildcards')->with('role')->whereParentRoleId($this->id)->get();

Perl DBIx::Class encounterd Object Json

I'm new to Perl and DBIx::Class.
This is how I get my meaning_ids from the table translation where language = 5:
my $translations = $schema -> resultset('Translation')->search({ language => '5'});
After it I'm trying to push my data from the database into my array data:
while ( my $translation =$translations->next ) {
push #{ $data }, {
meaning_id => $translation-> meaning
};
}
$self->body(encode_json $data );
If I do it like this, I get the following error:
encountered object
'TranslationDB::Schema::Result::Language=HASH(0x9707158)', but neither
allow_blessed , convert_blessed nor allow_tags settings are enabled
(or TO_JSON/FREEZE method missing)
But if I do it like that:
while ( my $translation =$translations->next ) {
push #{ $data }, {
meaning_id => 0+ $translation-> meaning
};
}
$self->body(encode_json $data );
I don't get the error anymore, but the meaning is not the number out of the database. It's way too big (something like 17789000, but only numbers till 7000 are valid).
Is there an easy way to tell Perl that meaning_id is an INT and not a string?
It's a bit hard without knowing your schema classes, but #choroba is right. The error message says $translation->meaning is an instance of TranslationDB::Schema::Result::Language. That's explained in DBIx::Class::Manual::ResultClass on CPAN.
I believe there is a relationship to a table called meaning, and when you call $translation->meaning what you get is a new result class. Instead you need to call $translation->meaning_id. Actually that would only happen in a join, but your code doesn't look like it does that.
It seems $translation->meaning returns an object. Using 0+ just returns its address (that's why the numbers are so high).
It looks like there's a relationship between your translation and meaning tables. Probably, the translation table contains a foreign key to the meaning table. If you look in the Result class for your translation class then you will see that relationship defined - it will be called "meaning".
As you have that relationship, then DBIC has added a meaning method to your class which retrieves the meaning object that is associated with your translation.
But it appears that the foreign key column in your translation table is also called "meaning", so you expect calling the "meaning" method gives you the value of the foreign key rather than the associated object. Unfortunately it doesn't work like that. The relationship method overrides the column method.
This is a result of bad naming practices. I recommend that you call the primary key for every table id and the foreign key that links to another table <table_name>_id - so the column in your translation table would be called meaning_id. That way you can distinguish between the value of the key ($translation->meaning_id) and the associated meaning object ($translation->meaning).
A work-around you can use if you can't rename columns, is to use the get_column method - $translation->get_column('meaning').

Delete entry in couchbase bucket using key in the form of regex

I have a requirement wherein I have to delete an entry from the couchbase bucket. I use the delete method of the CouchbaseCient from my java application to which I pass the key. But in one particular case I dont have the entire key name but a part of it. So I thought that there would be a method that takes a matcher but I could not find one. Following is the actual key that is stored in the bucket
123_xyz_havefun
and the part of the key that I have is xyz. I am not sure whether this can be done. Can anyone help.
The DELETE operation of the Couchbase doesn't support neither wildcards, nor regular expressions. So you have to get the list of keys somehow and pass it to the function. For example, you might use Couchbase Views or maintain your own list of keys via APPEND command. Like create the key xyz and append to its value all the matching keys during application lifetime with flushing this key after real delete request
Well, I think you can achieve delete using wildcard or regex like expression.
Above answers basically says,
- Query the data from the Couchbase
- Iterate over resultset
- and fire delete for each key of your interest.
However, I believe: Delete on server should be delete on server, rather than requiring three steps as above.
In this regards, I think old fashioned RDBMS were better all you need to do is fire SQL query like 'DELETE * from database where something like "match%"'.
Fortunately, there is something similar to SQL is available in CouchBase called N1QL (pronounced nickle). I am not aware about JavaScript (and other language syntax) but this is how I did it in python.
Query to be used: DELETE from b where META(b).id LIKE "%"
layer_name_prefix = cb_layer_key + "|" + "%"
query = ""
try:
query = N1QLQuery('DELETE from `test-feature` b where META(b).id LIKE $1', layer_name_prefix)
cb.n1ql_query(query).execute()
except CouchbaseError, e:
logger.exception(e)
To achieve the same thing: alternate query could be as below if you are storing 'type' and/or other meta data like 'parent_id'.
DELETE from where type='Feature' and parent_id=8;
But I prefer to use first version of the query as it operates on key, and I believe Couchbase must have some internal indexes to operate/query faster on key (and other metadata).
Although it is true you cannot iterate over documents with a regex, you could create a new view and have your map function only emit keys that match your regex.
An (obviously contrived and awful regex) example map function could be:
function(doc, meta) {
if (meta.id.match(/_xyz_/)) {
emit(meta.id, null);
}
}
An alternative idea would be to extract that portion of the key from each document and then emit that. That would allow you to use the same index to match different documents by that particular key form.
function(doc, meta) {
var match = meta.id.match(/^.*_(...)_.*$/);
if (match) {
emit(match[1], null);
}
}
In your case, this would emit the key xyz (or the corresponding component from each key) for each document. You could then just use startkey and endkey to limit based on your criteria.
Lastly, there are a ton of options from the information retrieval research space for building text indexes that could apply here. I'll refer you to this doc on permuterm indexes to get you started.

How to correctly define one-to-many relations with existing joint table using node Sequelize

I am using Sequelize, but since I also have other servers running other than node.js, I need to let them share the database. So when defining one-to-many relation, I need to let Sequelize use the old existing jointTable.
I write my definition of the association as below, where pid is the primary key of presentations:
this.courses.hasMany(this.presentations,
{as : 'Presentations',
foreignKey : 'cid',
joinTableName : 'course_presentations'
});
Or this one:
this.courses.hasMany(this.presentations,
{as : 'Presentations',
foreignKey : 'pid',
joinTableName : 'course_presentations'
});
I am using the below codes to retrieve the associated presentations:
app.get('/courses/presentations/:cid', function (req, res){
var cid = req.params.cid;
app.models.courses.find({where: {cid:cid}}).success(function(course){
course.getPresentations().success(function(presentations){
res.send(presentations);
});
});
});
The previous one will tell me there is no cid in 'presentations' table.
The latter one will give something like this:
Executing: SELECT * FROM `courses`;
Executing: SELECT * FROM `courses` WHERE `courses`.`cid`='11' LIMIT 1;
Executing: SELECT * FROM `presentations` WHERE `presentations`.`pid`=11;
Check carefully, I found that everytime, it is always using the cid value to query for presentations, which means only when they happen to share the same id value, something can be returned. And even for those, it is not correct.
I am strongly suspecting, Sequelize are not using the joinTable I specified, instead, it is still trying to find the foreign keys in the original two tables. It is viewing pid as the reference of cid in presentations, which causes this problem.
So I am wondering how to correctly set up the junction table so that the two of them can use the foreign keys correctly.
jointTableName : 'course_presentations'
should be (without a t)
joinTableName : 'course_presentations'
Actually AFAIK - this kind of relation is not "pure" one-to-many.
You have one course can have many entries in course_presenation table, and course_presentation have one-to-one relation with presentation. If so, just define that kind of associations in model.

linq-to-sql How can I get a few rows that don't match my existing rows?

I have a few rows of data pulled into business objects via linq-to-sql from large tables.
Now I want to get a few rows that don't match to test my comparison functions.
Using what I thought would work I get a NotSupportedException:
Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.
Here's the code:
//This table has a 2 field primary key, the other has a single
var AllNonMatches = from c in dc.Acaps
where !Matches.Rows.Any((row) => row.Key.Key == c.AppId & row.Key.Value == c.SeqNbr)
select c;
foreach (var item in AllNonMatches.Take(100)) //Exception here
{}
The table has a compound primary key: AppId and SeqNbr.
The Matches.Rows is defined as a dictionary of keyvaluepair(appid,seqnbr).
and the local sequence it is referring to appears to be the local dictionary.
Could you provide more information on the structure and the name(s) of the table(s) plz?
Not sure what you're trying to do...
edit:
Ok.. I think I get it now...
It appears you can't merge/join local tables (dictionary) with a SQL table.
If you can, I'm afraid I don't know how to do it.
The simplest solution I can think of is to put those results in a table ("Match" for instance) with foreign keys related to your table "Acaps" and then use linq-to-sql, like:
var AllNonMatches = dc.Acaps.Where(p=>p.Matchs==null).Take(100).ToList();
Sorry I couldn't come up with any better =(
What about this:
var AllNonMatches = from c in dc.Acaps
where !(Matches.Rows.ContainsKey(c.AppId) && Matches.Rows.ContainsValue(c.SeqNbr))
select c;
That will work fine. I have also used a bitwise AND operator (&&) - I think thats the right term to help improve performance over the standard AND operator.