Is there a plugin, or what are your settings for formatting jooq methods? Curious to know if you have any rules that you could share). Below is an example
private Field<Set<Role>> getRolesSelect() {
return multiset(
select(USER_ROLE.AUTHORITY_ID.as(ROLE.ID))
.from(USER_ROLE)
.where(USER_ROLE.USER_ID.eq(USER.ID))
).as("roles")
.convertFrom(f -> f.intoSet(roleMapper));
}
or just
private Field<Set<Role>> getRolesSelect() {
return multiset(
select(USER_ROLE.AUTHORITY_ID.as(ROLE.ID))
.from(USER_ROLE)
.where(USER_ROLE.USER_ID.eq(USER.ID))).as("roles")
.convertFrom(f -> f.intoSet(roleMapper));
}
try to find out jooq convention
Related
My query looks like (using JOOQ v 3.15):
override fun getCredentialsById(id: Long): Mono<UserCredentialsModel> {
return Mono.from {
dsl.select(
USER_CREDENTIALS.ID,
USER_CREDENTIALS.EMAIL,
USER_CREDENTIALS.PHONE,
USER_CREDENTIALS.LOGIN,
USER_CREDENTIALS.PASSWORD)
.from(USER_CREDENTIALS)
.where(USER_CREDENTIALS.ID.eq(id))
.and(USER_CREDENTIALS.IS_ACTIVE.eq(true))
.fetchInto(UserCredentialsModel::class.java)
}
}
JOOQ config:
#Bean
fun createContext(): DSLContext {
return DSL.using(connection)
}
where connection is io.r2dbc.spi.ConnectionFactory
and I`m getting an exception:
org.jooq.exception.DetachedException: Attempt to execute a blocking method (e.g. Query.execute() or ResultQuery.fetch()) when only an R2BDC ConnectionFactory was configured
How should I then fetch my query result into Kotlin data class (or Java JOOQ`s POJO) in reactive style?
When using jOOQ reactively, you should never call any blocking methods, such as ResultQuery.fetchOneInto(Class). That method is just a convenience method for ResultQuery.fetchOne() and then Record.into(Class). Nothing keeps you from calling Record.into(Class) yourself, neither in the blocking world, nor in the non-blocking world.
So, use your usual reactor library methods to map stream contents:
mono.map { r -> r.into(UserCredentialsModel::class.java) }
Or, in a complete example:
return Mono.from {
dsl.select(
USER_CREDENTIALS.ID,
USER_CREDENTIALS.EMAIL,
USER_CREDENTIALS.PHONE,
USER_CREDENTIALS.LOGIN,
USER_CREDENTIALS.PASSWORD)
.from(USER_CREDENTIALS)
.where(USER_CREDENTIALS.ID.eq(id))
.and(USER_CREDENTIALS.IS_ACTIVE.eq(true))
} .map { r -> r.into(UserCredentialsModel::class.java) }
Without testing I would say it should be
return Mono.from(
dsl.select(
USER_CREDENTIALS.ID,
USER_CREDENTIALS.EMAIL,
USER_CREDENTIALS.PHONE,
USER_CREDENTIALS.LOGIN,
USER_CREDENTIALS.PASSWORD)
.from(USER_CREDENTIALS)
.where(USER_CREDENTIALS.ID.eq(id))
.and(USER_CREDENTIALS.IS_ACTIVE.eq(true)));
You can try .toMono().subscribe()
dsl.select(
USER_CREDENTIALS.ID,
USER_CREDENTIALS.EMAIL,
USER_CREDENTIALS.PHONE,
USER_CREDENTIALS.LOGIN,
USER_CREDENTIALS.PASSWORD)
.from(USER_CREDENTIALS)
.where(USER_CREDENTIALS.ID.eq(id))
.and(USER_CREDENTIALS.IS_ACTIVE.eq(true))
.fetchInto(UserCredentialsModel::class.java)
.toMono().subscribe()
We are using fluentvalidation (with service stack) to validate our request DTO's. We have recently extended our framework to accept "PATCH" requests, which means we now have a requirement to apply validation ONLY when the patch contained the field being validated.
We have done this using an extension method such as this:
RuleFor(dto => dto.FirstName).Length(1,30)).WhenFieldInPatch((MyRequest dto)=>dto.FirstName);
RuleFor(dto => dto.MiddleName).Length(1,30)).WhenFieldInPatch((MyRequest dto)=>dto.MiddleName);
RuleFor(dto => dto.LastName).Length(1,30)).WhenFieldInPatch((MyRequest dto)=>dto.LastName);
This means we can run the same validation for a POST/PUT or a PATCH.
I have been looking for a way of hooking in to the fluent validation framework in such as way that we do not need to duplicate the .WhenFieldInPatch() rule on EVERY line in our validations, but have not yet found a nice way to do this.
I have tried the following:
Creating a helper method (in a in a base class) to intercept the initial "RuleFor" which adds the .When() clause up front, but the this does not work as fluent validation requires the .When() to be last
Intercepting the calls in PreValidation, but I can only intercept based on the whole class, and not on a rule by rule basis
Adding an extension method to apply to the end of every rule (as per example), but I cannot access the initial expression in order to check whether the field should be mapped - so I need to pass it in again.
Am I missing something, or am I attempting the impossible?
Thanks
When I need to share Fluent Validation Logic I'd use extension methods, here's an example of shared Extension methods for TechStacks, e.g:
public static class ValidatorUtils
{
public static bool IsValidUrl(string arg) => Uri.TryCreate(arg, UriKind.Absolute, out _);
public static string InvalidUrlMessage = "Invalid URL";
public static IRuleBuilderOptions<T, string> OptionalUrl<T>(
this IRuleBuilderInitial<T, string> propertyRule)
{
return propertyRule
.Length(0, UrlMaxLength)
.Must(IsValidUrl)
.When(x => !string.IsNullOrEmpty(x as string))
.WithMessage(InvalidUrlMessage);
}
}
And some examples where they're shared:
public class CreatePostValidator : AbstractValidator<CreatePost>
{
public CreatePostValidator()
{
RuleSet(ApplyTo.Post, () =>
{
RuleFor(x => x.Url).OptionalUrl();
});
}
}
public class UpdatePostValidator : AbstractValidator<UpdatePost>
{
public UpdatePostValidator()
{
RuleSet(ApplyTo.Put, () =>
{
RuleFor(x => x.Url).OptionalUrl();
});
}
}
I have the need to extend Service/IService to allow me to register additional resources like other DB connections and custom classes that each individual service may need to get a handle to.
Is the proper way to do this to subclass Service? Also, it is not clear to me if I have another (say) IDbConnection how Funq figures out which Property to inject the value into.
If you have multiple services with the same type you need to register them in funq with a name. Unfortunatly I don't think funq can autowire the properties correctly so you need to manually resolve them.
container.Register<DataContext>("Security", x => new SecurityDataContext());
container.Register<DataContext>("Customers", x => new CustomersDataContext());
container.Register<DataContext>("Reporting", x => new ReportingDataContext());
container.Register<IReportRepository>(x => new ReportRepositoryImpl(x.ResolveNamed<DataContext>("Reporting")));
An alternative approach would be to create a unique interface (even if it has no members) for each type and then use that in funq. This would allow autowiring
container.Register<ISecurityDataContext>(x => new SecurityDataContext());
container.Register<ICustomersDataContext>(x => new CustomersDataContext());
container.Register<IReportingDataContext>(x => new ReportingDataContext());
// this could just be autowired
container.Register<IReportRepository>(x => new ReportRepositoryImpl(x.Resolve<IReportingDataContext>()));
If you still really need to extend Service you can just use standard inheritance in c#
public abstract class BaseService : Service
{
// custom things go here
public string Example() {
return "Hello World";
}
}
public class ReportsService : BaseService
{
public string Get(ListReports request) {
return Example();
}
}
You can configure other DB connections easily without extending the Service , but by just wiring them in the configure method in the AppHost.cs file.
I have an Orchard cms module with some additional Content types set up and have added an AutoRoute component via code.
Everything works perfectly, however I am not happy with the default permalink pattern.
What I am trying to do is add a custom pattern and use one of the public properties in my content type. In my case the custom type has a public property called ClubName and I would like that to be used (It makes more sense from a routing perspective).
The Orchard part class name is called TrackPart.
I have tried {Content.TrackPart.ClubName}, {Content.Track.ClubName}, {ContentItem.TrackPart.ClubName},{Content.TrackPart.ClubName} and various other variations but nothing seems to be working.
I am really new to Orchard so there is a high chance I am missing something simple.
Any help would be greatly appreciated.
In response to feedback from #Bertrand-le-roy I created my own token by copying an example token. I can now get see the token in the drop down menu and select it. However the route pattern is still not working.
I can only assume that I have misunderstood the Evaluate() function's context.For usage. It looks like I am not getting the data I need
Here is what I have so far.
public class TrackPartTokens : ITokenProvider {
private readonly IContentManager _contentManager;
public TrackPartTokens(IContentManager contentManager) {
_contentManager = contentManager;
}
public Localizer T { get; set; }
public void Describe(dynamic context) {
context.For("Track", T("Track"), T("Tokens for Track"))
.Token("ClubName", T("ClubName"), T("The name of the club."))
;
}
public void Evaluate(dynamic context) {
context.For<TrackPart>("Track")
.Token("ClubName", (Func<TrackPart, object>)(field => field.ClubName))
.Chain("ClubName", "ClubName", (Func<TrackPart, object>)(field =>field.ClubName))
;
}</code>
The above code was based on the DateTimeField token inside the Orchard.Fields module.
context.For("DateTimeField")
.Token("Date", (Func)(field => field.DateTime))
.Chain("Date", "Date", (Func)(field => field.DateTime));
I had the same issue.
After some troubleshooting I managed to get the autoroute working by changing my implementaion to the following (adapted to your example, note that your setup might require some changes to the linq-function):
In your tokens-class:
First add a using System.Linq statement.
Then change your Evaluate implementation to the following:
context.For<IContent>("Content")
.Token("ClubName", (Func<IContent>, object>)(content =>
content.ContentItem.Parts.OfType<TrackPart>().First().ClubName));
Make sure your AutoroutePart settings in Migrations.cs uses the Content-prefix. Like:
.WithPart("AutoroutePart", partBuilder =>
partBuilder
.WithSetting("AutorouteSettings.AllowCustomPattern", "true")
.WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false")
.WithSetting("AutorouteSettings.PatternDefinitions",
#"[{Name:'Track', Pattern:'{Content.ClubName}',
Description:'Your description'}]")
.WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
There seems to be some problems with the TokenManager-class in Orchard source that only allows the target-parameter to equal "Content" in order for the call: _data.TryGetValue(target, out value) to work (TokenManager.cs, line 67). I have tried a number of different setups but the _data-dictionary always only contain the "Content" key.
You'll have to make your own token. It's really easy. Copy a working example.
I am currently using CSS to change everything I write to upperCase when I create an entry, but that is not enough. When I save things, the text shown in the text fields is upper case, but the real value that Grails stores stays in lower case.
I am assuming I'd need to change something in the controller or anything.
Maybe transforming the $fieldValue CSS could work??
Any ideas would help!
Thnks!
You could just write setters for your domain object?
class Domain {
String aField
void setAField( String s ){
aField = s?.toUpperCase()
}
}
I think you are asking how to change values on your domain objects to uppercase. If this is not the case please clarify the question.
You have a bunch of options. I would recommend
1) In a service method, before you save, using String.toUpperCase() to modify the appropriate values on the domain object.
or
2) You can use the underlying Hibernate interceptors by defining a beforeInsert method on your domain object, and doing the toUpperCase there. (see 5.5.1 of the grails documentation)
or
3) You could do this client side. However, if it is a "business requirement" that the values are stored as upper, then I recommend doing the translation server side. It is easier to wrap tests around that code....
Using annotations is cleanest approach
import org.grails.databinding.BindingFormat
class Person {
#BindingFormat('UPPERCASE')
String someUpperCaseString
#BindingFormat('LOWERCASE')
String someLowerCaseString
}
Here is link for it: Grails doc for data binding
You can use Groovy metaprogramming to change the setter for all domain class String-typed properties without actually writing a custom setter for each property.
To do this, add something like the following to the init closure of Bootstrap.groovy
def init = { servletContext ->
for (dc in grailsApplication.domainClasses) {
dc.class.metaClass.setProperty = { String name, value ->
def metaProperty = delegate.class.metaClass.getMetaProperty(name)
if (metaProperty) {
// change the property value to uppercase if it's a String property
if (value && metaProperty.type == String) {
value = value.toUpperCase()
}
metaProperty.setProperty(delegate, value)
} else {
throw new MissingPropertyException(name, delegate.class)
}
}
}
}